2009-10-05 43 views
3

在過去禁用外鍵檢查的數據庫中,如何檢查外鍵約束違規如何尋找整個數據庫的外鍵違規? (我正在使用MySQL)

+0

我覺得這是更好地發現,你把壞的數據進入數據庫之前處理「頭痛」。通過關閉外鍵使事情變得更容易,你會讓事情變得更糟,並且破壞了開始使用外鍵的全部目的。預處理數據。不要將有害數據明知地放入數據庫中。 – HLGEM 2009-10-05 17:16:51

+1

您可以使用http://stackoverflow.com/a/5977191/950503檢查所有外鍵違規。 – windm 2012-10-06 09:43:07

回答

-1

啓用外鍵約束將檢查所有關係,所以如果出現錯誤,您將會收到錯誤。

+1

由於某種原因,該問題具有外鍵約束被禁用的假設。並且在數據加載後將它們重新打開不會導致mysql檢查現有數據。那麼這個答案如何有用? – longneck 2009-10-05 14:29:29

+1

請證明,如果存在違規,啓用外鍵在MySQL中不會失敗。如果那是真的,那麼外鍵就沒用了。如果存在錯誤,請使用ALTER TABLE刪除FK約束,然後添加它們:添加FK約束時,DB *必須檢查數據。 – 2009-10-05 14:41:14

+1

mysql支持外鍵,並強制執行它們。但它也允許您暫時禁用這些密鑰的強制執行,以加快關係數據的數據導入速度。請參閱http://dev.mysql.com/doc/refman/5.0/en/server-session-variables.html#sysvar_foreign_key_checks – longneck 2009-10-05 14:45:09

0

有沒有內置的方式來做到這一點。我唯一能想到的就是查看INFORMATION_SCHEMA數據庫中的TABLE_CONSTRAINTSKEY_COLUMN_USAGE表以手動檢查不匹配的行。

-1

「打開」FK後,負載應該確實已經做了檢查。

如果您的DBMS不這樣做,請轉儲它。

如果你的數據庫管理系統沒有這樣做,你仍然想繼續處理這種垃圾,你可以查詢RA的適當SEMIMINUS表達式。

這可能看起來像:

SELECT ... FROM table_with_FK WHERE NOT EXISTS( SELECT ... FROM table_with_PK WHERE PK_attribute1 = FK_attribute1和PK_attribute2 = FK_attribute2和... )和<東西在這裏,讓你識別裝載的行>

或略偏現代(如果你的DBMS支持除):

SELECT FK_attributes FROM table_with_FK WHERE <東西在這裏,讓你識別裝載的行> EXCEPT SELECT PK_attributes_possibly_renamed FROM table_with_PK ;

EDIT(回答爲「不是每個人都需要甲骨文和IBM尺寸的產品。‘傾倒’是不是很好的建議。」)

的OP已經非常清楚地表明,他是在數據的完整性很有興趣。所以他真的應該使用一個DBMS產品,它提供了一些專業級的支持來確保數據的完整性。我真誠地希望「Oracle和IBM大小的產品」不是唯一那樣做的人。

+0

不是每個人都需要oracle和IBM大小的產品。 「傾倒它」並不是很好的建議。 – longneck 2009-10-05 17:08:35

+0

@longneck:有更多的DBMS產品比Oracle和IBM更多。事實上,考慮到用戶已經在使用MySQL,如果他轉儲MySQL,PostgreSQL將成爲下一個合理的選擇。 – Powerlord 2009-10-05 17:27:17

0

這聽起來像你基本上可以將你的問題改寫爲「我如何確保禁用外鍵的參照完整性?」

我想象一下讓你禁用外鍵的非常「頭痛」是他們打算執行的事情。所以對我來說最簡單的答案似乎並不是首先禁用它們。第一次做對,你以後不必再做。

+1

這沒有幫助。 *「問:我如何治療手臂骨折?答:不要折斷你的手臂。」*呃,好吧,但是*我手臂骨折,這就是我來這裏的原因。 – 2016-10-11 12:37:27

2

基本上,如果你有沒有外鍵約束,你可以這樣做:

SELECT * FROM CHILD C WHERE C.PARENT_ID NOT IN (SELECT ID FROM PARENT); 
+1

-1;首先,OP描述的情況並不是*「你沒有外鍵約束」*,其次,這忽略了問題中的「整個數據庫」條件。 – 2016-10-12 12:20:00