在远距离相关的表格中实施参照完整性

时间:2013-08-12 16:03:54

标签: sql sql-server tsql database-normalization referential-integrity

我有四张桌子,看起来有点像这样:

CREATE TABLE [TableA]
    ( [ID]    INT     NOT NULL IDENTITY (1, 1) PRIMARY KEY )
CREATE TABLE [TableB]
    ( [A_ID]  INT     NOT NULL FOREIGN KEY REFERENCES [TableA] ([ID]) 
    , [Value] TINYINT NOT NULL 
    , PRIMARY KEY ( [A_ID], [Value] ) )
CREATE TABLE [TableC]
    ( [ID]    INT     NOT NULL IDENTITY (1, 1) PRIMARY KEY
    , [A_ID]  INT     NOT NULL FOREIGN KEY REFERENCES [TableA] ([ID]) )
CREATE TABLE [TableD]
    ( [ID]    INT     NOT NULL IDENTITY (1, 1) PRIMARY KEY
    , [C_ID]  INT     NOT NULL FOREIGN KEY REFERENCES [TableC] ([ID])
    , [Value] TINYINT NOT NULL )

但我想在TableD上强制执行引用完整性,以使有效值可能只是与父{{1}相关联的TableB TableA的值之一记录。例如:

TableC

现在,我尝试将TableA: ID 1 TableB: A_ID | VALUE 1 | 1 1 | 2 TableC: ID | A_ID 7 | 1 TableD: ID | C_ID | VALUE 1 | 7 | 1 -- Fine, Inserted 1 | 7 | 2 -- Fine, Inserted 1 | 7 | 3 -- Invalid, Rejected! 列添加到A_ID,如下所示:

TableD

但是我收到以下错误:

  

Msg 1776,Level 16,State 0,Line 2
  引用的表“CREATE TABLE [TableD] ( [ID] INT NOT NULL IDENTITY (1, 1) PRIMARY KEY , [C_ID] INT NOT NULL , [A_ID] INT NOT NULL , [Value] TINYINT NOT NULL , FOREIGN KEY ([C_ID], [A_ID]) REFERENCES [TableC] ([ID], [A_ID]) , FOREIGN KEY ([A_ID], [Value]) REFERENCES [TableB] ([A_ID], [Value]) ) ”中没有主键或候选键与外键“TableC”中的引用列列表匹配。

     

Msg 1750,Level 16,State 0,Line 2
  无法创建约束。查看以前的错误。

我真的不喜欢这个解决方案,因为它似乎是非规范化的 - 因为我将FK__TableD__TableCTableC关系存储在两个不同的地方 - 但我想不出任何其他方式强制引用完整性(触发器除外,我想避免)。

有没有办法实现这个目标?

1 个答案:

答案 0 :(得分:1)

是的,有办法。您可以向表unique添加TableC约束:

CREATE TABLE [TableC]
    ( [ID]    INT     NOT NULL IDENTITY (1, 1) PRIMARY KEY
    , [A_ID]  INT     NOT NULL FOREIGN KEY REFERENCES [TableA] ([ID]),
     CONSTRAINT UK_TableC UNIQUE ([ID], [A_ID]) )

然后您可以按照指定在表TableC中引用TableD

CREATE TABLE [TableD]
    ( [ID]    INT     NOT NULL IDENTITY (1, 1) PRIMARY KEY
    , [C_ID]  INT     NOT NULL 
    , [A_ID]  INT     NOT NULL 
    , [Value] TINYINT NOT NULL
    , FOREIGN KEY ([C_ID], [A_ID]) REFERENCES [TableC] ([ID], [A_ID])
    , FOREIGN KEY ([A_ID], [Value]) REFERENCES [TableB] ([A_ID], [Value]) )