我正在尝试创建SQL表来表示第三方API使用的一系列代码。到目前为止,我有以下表格:
CREATE TABLE ApiCode (
Id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
ResponseCode char(1) NOT NULL,
ResponseSubCode char(1) NOT NULL,
ResponseSubSubCode char(1) NULL,
MinorCodeRangeId int NULL REFERENCES ApiMinorCodeRange,
Description nvarchar(500)
)
CREATE TABLE ApiMinorCodeRange (
Id int NOT NULL IDENTITY(1, 1) PRIMARY KEY,
FromMinorCode char(4) NOT NULL,
ThruMinorCode char(4) NOT NULL
)
CREATE TABLE ApiMinorCode (
Code char(4) NOT NULL PRIMARY KEY,
Description nvarchar(500)
)
问题是,FromMinorCode
和ThruMinorCode
可以引用不存在的代码。例如:范围可以指示“5000 - 5ZZZ”,但MinorCode
可能只有“5000 - 500A”的条目。每隔几个月就会添加新代码,因此ApiMinorCodeRange
表需要引用规范中定义的整个范围。
我计划创建外键并将其标记为NOCHECK
:
ALTER TABLE ApiMinorCodeRange ADD CONSTRAINT FK_FromMinorCode FOREIGN KEY ( FromMinorCode ) REFERENCES ApiMinorCode
ALTER TABLE ApiMinorCodeRange NOCHECK CONSTRAINT FK_FromMinorCode
ALTER TABLE ApiMinorCodeRange ADD CONSTRAINT FK_ThruMinorCode FOREIGN KEY ( ThruMinorCode ) REFERENCES ApiMinorCode
ALTER TABLE ApiMinorCodeRange NOCHECK CONSTRAINT FK_ThruMinorCode
这在语义上是否正确?
对于引用虚构行的外键,Sql Server的查询优化器是否正常?
我应该创建一个虚拟值“5ZZZ - 保留供将来使用”而不是设置“NoCheck”吗?
答案 0 :(得分:1)
您正在尝试实施适用于您尚未看到的代码的业务规则。没有必要采用“正确”的方式来做到这一点。
范围关系是否必须包含有效代码?我不明白为什么。例如,一组百科全书中的picture(记住那些吗?)在每个卷上都有范围,例如:
我不认为“sto”是该卷中的有效条目。我确实假设“随机过程”将在卷中。
为什么您的代码会有所不同?在您的情况下更有针对性,即使'5'
可能不是有效代码,您案例中的范围也可能'5ZZZ'
到'5'
。
而且,您的规则最终可能超出范围。也许一些主要代码的所有次要代码都以“5”开头,以“Z”结尾。
我对范围的结论是不需要外键关系。
那就是说,还有一个问题,你可能想要处理。什么阻止代码在多个范围内?我怀疑你需要一个触发器来强制执行这条规则。