2010-01-27 36 views
3

我刚刚遇到了一个有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,但我对人们认为一般行为会是什么感兴趣。

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

回答

2

这并没有增加任何好处,而且是多余的。事实上,它是插入或更新a_id时需要检查的FK数量的两倍。

我说删除重复项。

如果一个具有级联和其他不那么非级联一个是重复的(可能不适用于Postgres的)

+0

无级联/非级联差 - 绝对相同! 额外的验证正是我所担心的! – azp74 2010-01-27 23:22:04

+0

你应该接受这个或其他答案,然后请:-) – gbn 2010-01-28 06:40:45

+0

对不起,延迟! – azp74 2010-01-29 03:47:48

1

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

删除冗余声明。我想不出一个理由。而且,如果你有一个创建脚本,那么也应该删除那些重复的声明。走着瞧吧。

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

+0

AFAIK没有创建脚本(我怀疑休眠'创建'数据库...)。 是的,我的部分工作将是编写一个用于生成测试数据库的脚本。因此,本质上,DDL的一部分将成为创建脚本。 – azp74 2010-01-27 23:19:37

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约束包括重复,

+0

问题是:为什么你会在数据库中有重复的外键约束?你的脚本不回答这个问题。你能改善你的答案吗? – Josien 2012-09-14 10:44:39

+0

当使用Grails Framework工作PostgreSQL时,框架本身创建了外键约束(名称类似“fk01645646fhgfad”),即使DBA也为此创建了fk约束。那时我们必须确定重复的fk约束。上面的脚本就是为了这个。 – solaimuruganv 2012-09-14 14:07:41