重复的外键约束 - 原因或反对

时间:2010-01-27 04:26:44

标签: sql database database-design foreign-keys

我刚刚遇到一个生产中有4个外键约束的表。其中两个约束与另外两个约束完全重复。

fk1(a_id) references a(id)
fk2(a_id) references a(id)
fk3(b_id) references b(id)
fk4(b_id) references b(id)

我之前从未见过这样......它让我觉得非常错误,我的直觉是这里必须有性能打击(特别是在插入此表时)。在这种情况下,数据库是PostGres,但我对人们认为的一般行为感兴趣。

如果有人经历过你想要这样的外键的时候我也会感兴趣 - 特别是因为我打算建议摆脱重复的事情!

3 个答案:

答案 0 :(得分:2)

这根本不会带来任何好处,而且是多余的。实际上,它是需要检查插入或更新a_id的FK数量的两倍。

我说放弃重复。

如果有一个级联而另一个没有级联,那么非级联的是副本(可能不适用于PostGres)

答案 1 :(得分:1)

你有数据库的创建脚本吗?如果你这样做,该脚本可能会揭示原因 同一个约束被多次声明。

清除冗余声明。我想不出有理由不这样做。而且,如果您有一个创建脚本,那么也要消除那里的冗余声明。看看会发生什么。

如果您没有创建脚本,可以考虑生成和维护一个。这是管理良好的数据库的重要文档。

答案 2 :(得分:1)

SELECT
    pc.conname as constraint_name, 
    --conrelid as child_table_id,   
    pclsc.relname as child_table,
    --pc.conkey as child_column_id,
    pac.attname as child_column,
    --confrelid as parent_table_id,
    pclsp.relname as parent_table,
    --pc.confkey as parent_column_id,
    pap.attname as parent_column,   
    nspname as schema_name
FROM 
    (
    SELECT
         connamespace,conname, unnest(conkey) as "conkey", unnest(confkey)
          as "confkey" , conrelid, confrelid, contype
     FROM
        pg_constraint
    ) pc
    JOIN pg_namespace pn ON pc.connamespace = pn.oid
    -- and pn.nspname = 'panmydesk4400'
    JOIN pg_class pclsc ON pc.conrelid = pclsc.oid
    JOIN pg_class pclsp ON      pc.confrelid = pclsp.oid
    JOIN pg_attribute pac ON pc.conkey = pac.attnum    and pac.attrelid =       pclsc.oid
    JOIN pg_attribute pap ON pc.confkey = pap.attnum and pap.attrelid = pclsp.oid

ORDER BY pclsc.relname

它列出了所有(包括重复的)FK约束,包括重复,