我有三张桌子,比如tableA,tableB,tableC。 这些表的关系是:
tableA:
CREATE TABLE tableA (
id int Not Null,
name varchar(50) Not Null,
Area varchar(20) Not Null,
CONSTRAINT PK_tableA PRIMARY KEY NONCLUSTERED(id Asc) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
)
tableB的:
CREATE TABLE tableB (
id int Not Null,
appNbr int NOT NULL,
appCode char(8) NOT NULL,
tableAId int Not Null,
beginDt datetime Not Null,
EndDt datetime Not Null,
updatedDt datetime Not Null,
CONSTRAINT PK_tableB PRIMARY KEY NONCLUSTERED(
id Asc,
appNbr ASC,
appCode ASC,
tableAid ASC,
beginDt ASC,
endDt ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
)
GO
ALTER TABLE tableB WITH CHECK ADD CONSTRAINT FK_tableB_tableAId FOREIGN KEY(tableAId)
REFERENCES tableA (Id)
GO
ALTER TABLE tableB CHECK CONSTRAINT FK_tableB_tableAId
GO
表C:
CREATE TABLE tableC (
id int Not Null,
tableBId int Not Null,
beginDt datetime Not Null,
endDt datetime Not Null,
indicator char(1) Not Null,
contactId int Not Null
UpdateDt datetime Not Null,
CONSTRAINT PK_tableC PRIMARY KEY NONCLUSTERED(
id ASC,
tableBId Asc,
beginDt ASC,
endDt ASC
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
)
ALTER TABLE tableC WITH CHECK ADD CONSTRAINT FK_tableC_tableBId FOREIGN KEY(tableBId)
REFERENCES tableB (Id)
GO
ALTER TABLE tableC CHECK CONSTRAINT FK_tableC_tableBId
GO
这里的问题是当我运行脚本来创建表C时,它显示错误如下
There are no primary or candidate keys in the referenced table
'dbo.tableB' that match the referencing column list in the
foreign key 'FK_tableC_tableBId'.
Msg 1750, Level 16, State 0, Line 2
Could not create constraint. See previous errors.
在谷歌研究后,我发现不允许从复合主键创建一个外键。所以,我决定将id作为我的主键和剩余字段(appNbr,appCode,tableAid,beginDt和endDt)放到表B上的逻辑键中。我已经阅读了一些关于逻辑键的在线资料,但是不能理解。
任何人都可以向我解释一下逻辑键是什么,我如何在我的例子中使用它。
答案 0 :(得分:1)
不保证TableB.id是唯一的,这是外键引用的要求之一。因此,要么使用id作为TableB的主键CONSTRAINT PK_tableB PRIMARY KEY NONCLUSTERED(id)
,要么引用所有PK_tableB候选列CONSTRAINT FK_tableC_tableBId FOREIGN KEY(tableBId/*... and a column for each referenced column*/)
REFERENCES tableB (id, appNbr, appCode, tableAid, beginDt, endDt)
。
答案 1 :(得分:1)
一般来说,逻辑键是定义数据和表之间关系的任何东西。主键和外键是最常见的示例,尽管唯一和复合索引属于同一个保护伞。您必须拥有与您定义的任何FK完全匹配的PK或唯一索引。
听起来你理解这个问题以及如何解决它,但这有两种方法:
在tableB (id)
上添加唯一索引:
CREATE UNIQUE INDEX UI_bID ON dbo.tableB (id)
将tableB
上的PK更改为仅涵盖(id)
:
例如:
CREATE TABLE tableB (
id int Not Null,
appNbr int NOT NULL,
appCode char(8) NOT NULL,
tableAId int Not Null,
beginDt datetime Not Null,
EndDt datetime Not Null,
updatedDt datetime Not Null,
CONSTRAINT PK_tableB PRIMARY KEY NONCLUSTERED(
id Asc
) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, FILLFACTOR = 90)
)
然后在唯一索引中包含其他列:
CREATE UNIQUE INDEX UI_tableB ON dbo.tableB (
appNbr ASC,
appCode ASC,
tableAid ASC,
beginDt ASC,
endDt ASC)