2010-01-27 66 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