2012-10-17 75 views
2

有沒有辦法檢查MySQL中的外鍵完整性?例如;是否有可能通過information_schema中的數據庫檢查每個表是否違反約束條件?檢查MySQL中的外鍵

+0

你想看看國外ķ表的約束約束? – gks

+0

一些解決方案在這裏討論: http://stackoverflow.com/questions/2250775/force-innodb-to-recheck-foreign-keys-on-a-table-tables – ffeast

回答

1

我寫了一些SQL來做到這一點。

首先,必須收集的限制,表,列和子表信息的列表:

SELECT DISTINCT KEY_COLUMN_USAGE.CONSTRAINT_NAME, KEY_COLUMN_USAGE.TABLE_NAME, KEY_COLUMN_USAGE.COLUMN_NAME, KEY_COLUMN_USAGE.REFERENCED_TABLE_NAME, KEY_COLUMN_USAGE.REFERENCED_COLUMN_NAME 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE 
ON TABLE_CONSTRAINTS.CONSTRAINT_NAME=KEY_COLUMN_USAGE.CONSTRAINT_NAME 
WHERE TABLE_CONSTRAINTS.CONSTRAINT_TYPE="FOREIGN KEY" AND TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA=<YOUR_DATABASE>; 

一旦該信息被收集你然後遍歷返回的數據與下面的SQL:

SELECT PARENT_TABLE.COLUMN AS CHILD_ID, CHILD_TABLE.CHILD_REFERENCED_COLUMN AS PARENT_ID FROM <YOUR_DATABASE>.<THE_TABLE> 
LEFT JOIN <YOUR_DATABASE>.CHILD_TABLE ON PARENT_TABLE.COLUMN=CHILD_TABLE.CHILD_REFERENCED_COLUMN 
WHERE CHILD_TABLE.CHILD_REFERENCED_COLUMN IS NULL; 

Python代碼做,這是下面:

self.dbcur.execute("SELECT DISTINCT KEY_COLUMN_USAGE.CONSTRAINT_NAME, KEY_COLUMN_USAGE.TABLE_NAME, KEY_COLUMN_USAGE.COLUMN_NAME, KEY_COLUMN_USAGE.REFERENCED_TABLE_NAME, KEY_COLUMN_USAGE.REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ON TABLE_CONSTRAINTS.CONSTRAINT_NAME=KEY_COLUMN_USAGE.CONSTRAINT_NAME WHERE TABLE_CONSTRAINTS.CONSTRAINT_TYPE=\"FOREIGN KEY\" AND TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA=%s", (self.database,)) 
prep = self.dbcur.fetchall() 

# 0 = CONSTRAINT_NAME 
# 1 = TABLE_NAME 
# 2 = COLUMN_NAME 
# 3 = REFERENCED_TABLE_NAME 
# 4 = REFERENCED_COLUMN_NAME 
# 5 = DATABASE 
for row in prep: 
    query = "SELECT {1}.{2} AS CHILD_ID, {3}.{4} AS PARENT_ID FROM {5}.{1} LEFT JOIN {5}.{3} ON {1}.{2}={3}.{4} WHERE {3}.{4} IS NULL".format(row[0], row[1], row[2], row[3], row[4], self.database) 
    self.dbcur.execute(query) 
    results = self.dbcur.fetchall() 

    if len(results) > 0: 
     for baddata in results: 
      bad_data = ({"CONSTRAINT_NAME": row[0], "TABLE_NAME": row[1], "COLUMN_NAME": row[2], "REFERENCED_TABLE_NAME": row[3], "REFERENCED_COLUMN_NAME": row[4], "CHILD_ID": baddata[0], "PARENT_ID": baddata[1], "DATABASE": self.database}) 
      self.badforeignkeys.append(bad_data) 

return(self.badforeignkeys)