我在两个用于管理自定义UI品牌的表之间有一个非常简单的关系:
ui_portal_branding
CREATE TABLE ui_portal_branding
(
id VARBINARY(16) NOT NULL,
branding_type VARCHAR(128) NOT NULL,
portal_name NVARCHAR(128) NOT NULL,
theme_id VARBINARY(16) NOT NULL,
portal_logo VARBINARY(16) NULL,
portal_favicon VARBINARY(16) NULL,
background_color VARCHAR(50) NULL,
organization_id VARBINARY(16) NULL,
CONSTRAINT pk_ui_port_bran_id PRIMARY KEY (id)
)
ui_portal_resource
CREATE TABLE ui_portal_resource
(
id VARBINARY(16) NOT NULL,
mime_type NVARCHAR(128) NOT NULL,
binary_data VARBINARY(MAX) NOT NULL,
CONSTRAINT pk_ui_port_reso_id PRIMARY KEY (id)
)
Branding是主表,Resources是二进制数据的BLOB存储。品牌表中的portal_logo
和portal_favicon
都是资源表中的可选二进制数据。
我想将此定义为具有以下一般逻辑的外键约束:不需要定义徽标或favicon。如果已定义它们,则它们将ui_portal_resource.id
指向资源表中的记录。如果从资源表中删除数据,我想将品牌表中的相应列设置为null。我不想禁止资源删除,我不想将删除级联到品牌表。
所以我定义了以下内容:
ALTER TABLE ui_portal_branding
ADD CONSTRAINT fk_ui_port_bran2ui_port_reso
FOREIGN KEY (portal_logo) REFERENCES ui_portal_resource (id)
ON DELETE SET NULL
到目前为止一切顺利。现在我定义:
ALTER TABLE ui_portal_branding
ADD CONSTRAINT fk_ui_port_bran2ui_port_reso2
FOREIGN KEY (portal_favicon) REFERENCES ui_portal_resource (id)
ON DELETE SET NULL
突然间我们遇到了问题:
在表'ui_portal_branding'上引入FOREIGN KEY约束'fk_ui_port_bran2ui_port_reso2'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。
这对我来说似乎错了。我不介绍一个循环。它是两个表,其中外键在单个方向上定义。我想它可以技术上是多个级联路径 - 如果相同的资源是favicon和徽标它必须设置2个零空。但真的吗?这是SQL Server引擎的交易破坏者? Oracle和Postgres都认为这种情况是可以接受的。
这个问题是否有明智的解决方法?我对涉及触发器的解决方案不感兴趣。有没有更好的方法来建模数据?我希望资源表可以服务的不仅仅是品牌表,这导致当前的FK放置。但也许这是不可能的?