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_pictures 表中带有 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中文网其他相关文章!