SQL 中的循環引用:一個困境
在關聯式資料庫設計領域,出現了一個問題:兩個表是否可以接受相互參考?不幸的是,答案取決於所使用的特定資料庫管理系統 (DBMS) 和所需的功能。
問題
如給定範例資料庫結構所示,兩個表,products 和products_pictures,具有創建循環引用的外鍵約束:
products.DEFAULT_PICTURE_ID -> products_pictures.ID products_pictures.PRODUCT_ID -> products.ID
這種循環可能會導致
可能的解決方案
選項1:可調整外鍵可空性
一個解是使外鍵列之一可為空。這允許在不違反完整性約束的情況下對兩個表進行初始插入。但是,它可能會引入資料完整性問題,例如允許產品具有屬於其他產品的預設圖片。為了解決這個問題,外鍵約束可以定義如下:
CONSTRAINT FK_products_1 FOREIGN KEY (id, default_picture_id) REFERENCES products_pictures (product_id, id) ON DELETE RESTRICT ON UPDATE RESTRICT
選項2:IsDefault Flag
另一種方法是替換中的DEFAULT_PICTURE_ID 欄位products_picturesproduct 資料表中帶有IsDefault 標誌的產品表。此解決方案需要定義唯一約束或索引,以確保每個產品只有一張圖片的 IsDefault 標誌設為 true。但是,MySQL 不支援部分索引,這使得這種方法不切實際。
選項 3:可延遲約束
此選項涉及使用可延遲約束。可延遲約束允許資料庫暫時延遲實施完整性約束,從而允許對錶及其關係進行初始設定。但是,MySQL 不支援可延遲約束。
選項4:中間表
為了完全消除循環引用,可以引入第三個表:
product_default_picture ---------------------- product_id NOT NULL default_picture_id NOT NULL PRIMARY KEY (product_id) FOREIGN KEY (product_id, default_picture_id) REFERENCES products_pictures (product_id, id)
這種方法消除了循環並確保資料完整性。
MySQL建議
對於MySQL,有兩個選項仍然可行:
以上是如何解決SQL中的循環引用,尤其是MySQL中的循環引用?的詳細內容。更多資訊請關注PHP中文網其他相關文章!