多对多关系中约束的优缺点

问题描述 投票:0回答:1

我的表具有如下关系。

CREATE TABLE DocumentType
   ID uniqueidentifier primary key,
   ...
GO

CREATE TABLE LinkedDoc
   ID uniqueidentifier ROWGUIDCOL NOT NULL,
   DocumentTypeID uniqueidentifier NOT NULL,
   ...,
   CONSTRAINT [PK_LinkedDoc] PRIMARY KEY CLUSTERED
   (
      ID,
      DocumentTypeID
   )
GO

ALTER TABLE LinkedDoc ADD CONSTRAINT FK_DocumentType_LinkedDoc FORIGN KEY(DocumentTypeID)
REFRENCES DocumentType ID
GO

CREATE TABLE ManyToMany 
   ID uniqueidentifier primary key,
   LinkedDocID uniqueidentifier,
   DocumentTypeID uniqueidentifier
   SomeOtherTableID uniqueidentifier,
   CONSTRAINT IX_ManyToMany UNIQUE 
   (
      DocumentTypeID,
      SomeOtherTable
   )
GO

ALTER TABLE ManyToMany WITH CHECK ADD CONSTRAINT FK_LinkedDoc_ManyToMany FOREIGN KEY(LinkedDocID, DocumentTypeID)
REFERENCES LinkedDoc (ID, DocumentTypeID)
GO

我省略了一些与我的问题无关的细节。我的目标是构建表,以便 SomeOtherTable 中的每个唯一实体不能链接到具有给定文档类型的多个 LinkedDoc。这是通过上面的 IX_ManyToMany 约束实现的。

虽然它有效,但这个解决方案并不适合我,我想在将数据加载到系统之前立即更改它。主要关注点是 IX_ManyToMany 对表主键有部分依赖。另外 LinkedDoc 中的 ID 是 ROWGUIDCOL,这意味着我对该表的 pk 不是最小的。

有更好的选择吗?我愿意重构我的表,但我想避免数据库触发器和函数,因为那时我觉得我正在将业务逻辑放入数据库中。我更喜欢将 bl 保留在我的 api 中,它是受源代码控制且更易于维护的。

我发现了这个多对多关系表的约束 - 两个相关记录都需要引用相同的依赖记录?第一个答案与我的解决方案类似。第二个使用我愿意考虑的 db 函数,但想看看是否可以通过修改架构来完成。尽管如此,我可能会选择简单地允许数据库违反我的要求,然后在 api 中处理它,而不是使用函数解决方案。

sql-server many-to-many rdbms database-normalization
1个回答
0
投票

(ID,DocumentTypeID) 是 LinkedDoc 的主键,因此添加该约束实际上使其成为一对多关系。这意味着您不需要链接表,只需使用:

CREATE TABLE DocumentType
(
   ID uniqueidentifier primary key,
)

GO
CREATE TABLE LinkedDoc
(
   ID uniqueidentifier ROWGUIDCOL NOT NULL,
   DocumentTypeID uniqueidentifier NOT NULL,
   CONSTRAINT [PK_LinkedDoc] PRIMARY KEY CLUSTERED
   (
      ID,
      DocumentTypeID
   ),
   CONSTRAINT FK_DocumentType_LinkedDoc FOREIGN KEY(DocumentTypeID) REFERENCES DocumentType(ID)
)
CREATE TABLE SomeOtherTable
(
   ID uniqueidentifier primary key,
   LinkedDocID uniqueidentifier,
   DocumentTypeID uniqueidentifier,
   CONSTRAINT SomeOtherTable_LinkedDoc FOREIGN KEY(LinkedDocID, DocumentTypeID) REFERENCES LinkedDoc (ID, DocumentTypeID),
   INDEX IXSomeOtherTable_LinkedDoc(LinkedDocID, DocumentTypeID)
)
© www.soinside.com 2019 - 2024. All rights reserved.