TableA
,TableB
和TableC
都需要TableX
中的一行,但不能在表格的多行之间共享一行TableX
AC。 (表A-C完全不同)。
我可以想到一些解决方案,但哪一个(如果有的话)是正确的?
将TableX上的字段展平到表A-C上(我最不喜欢的选项)。
这实际上看起来像是一对一的链接,但最容易在数据库中以一对一的方式强制执行。使用实体框架不能很好地工作。
[Id] IDENTITY INT NOT NULL,
[TableAId] INT NULL,
[TableBId] INT NULL,
[TableCId] INT NULL,
CONSTRAINT [PK_TableX] PRIMARY KEY,
CONSTRAINT [FK_TableX_TableA] FOREIGN KEY [TableAId] REFERENCES [TableA]([Id]),
CONSTRAINT [FK_TableX_TableB] FOREIGN KEY [TableBId] REFERENCES [TableB]([Id]),
CONSTRAINT [FK_TableX_TableC] FOREIGN KEY [TableCId] REFERENCES [TableC]([Id]),
CONSTRAINT [UQ_TableX_TableAId] UNIQUE ([TableAId]),
CONSTRAINT [UQ_TableX_TableBId] UNIQUE ([TableBId]),
CONSTRAINT [UQ_TableX_TableCId] UNIQUE ([TableCId]),
CONSTRAINT [CK_TableX_Owner] CHECK
(
([TableAId] IS NOT NULL AND [TableBId] IS NULL AND [TableCId] IS NULL) OR
([TableBId] IS NOT NULL AND [TableCId] IS NULL AND [TableAId] IS NULL) OR
([TableCId] IS NOT NULL AND [TableAId] IS NULL AND [TableBId] IS NULL)
)
[Id] IDENTITY INT NOT NULL
这是我最喜欢的选项,因为它似乎代表最佳的一对一链接(因为我们不能使Id
TableX
与表AC的主键匹配。 ORM(在本例中为Entity Framework)将处理其余部分。
[Id] IDENTITY INT NOT NULL,
[TableXId] INT NOT NULL,
CONSTRAINT [PK_Table*] PRIMARY KEY,
CONSTRAINT [FK_Table*_TableX] FOREIGN KEY [TableXId] REFERENCES [TableX]([Id]) ON DELETE CASCADE
CONSTRAINT [UQ_Table*_TableXId] UNIQUE ([TableXId])
Id IDENTITY INT NOT NULL,
CONSTRAINT [PK_TableX] PRIMARY KEY
答案 0 :(得分:0)
选项4:
dbo.TableX
Id IDENTITY INT NOT NULL,
CONSTRAINT [PK_TableX] PRIMARY KEY,
Type CHAR(1) NOT NULL,
CONSTRAINT CK_TableX_VerifyType CHECK( Type IN ('A', 'B', 'C') ),
CONSTRAINT UQ_TableX_Id_Type UNIQUE (Id, Type)
dbo.Table {A | B | C}
[TableXId] INT NOT NULL,
CONSTRAINT [PK_Table*] PRIMARY KEY (TableXId),
CONSTRAINT [FK_Table*_TableX_TableXId] FOREIGN KEY ([TableXId]) REFERENCES [TableX]([Id]) ON DELETE CASCADE,
Type CHAR(1) NOT NULL,
CONSTRAINT CK_Table*_VerifyType CHECK( Type = 'A' ) -- For dbo.TableA or ='B' for dbo.TableB or ...
CONSTRAINT [FK_Table*_TableX_TableXId_Type] FOREIGN KEY ([TableXId], Type) REFERENCES [TableX]([Id], Type) ON DELETE CASCADE,
答案 1 :(得分:0)
这不是严格意义上的一对一"关系。这实际上是一组3"一个为零或一个"与"排他性" 的附加条件的关系(表A,B和C不能在X中共享一行)和"存在" (X中的一行不能没有A,B或C中的行。)
有关如何实际执行此操作的说明,请参阅:Supertype-subtype database design。
1 不幸的是,MS SQL Server属于该类别。
答案 2 :(得分:0)
您可以在A,B和C
上创建索引视图create view myView as
select xId from tableA
union all
select xId from tableB
union all
select xId from tableC
go
create unique clustered index [CIX_myView] on dbo.myView (xId)