使用外键指示范围在语义上是否正确?

时间:2014-04-28 16:42:44

标签: sql sql-server semantics

我正在尝试创建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)
)

问题是,FromMinorCodeThruMinorCode可以引用不存在的代码。例如:范围可以指示“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”吗?

1 个答案:

答案 0 :(得分:1)

您正在尝试实施适用于您尚未看到的代码的业务规则。没有必要采用“正确”的方式来做到这一点。

范围关系是否必须包含有效代码?我不明白为什么。例如,一组百科全书中的picture(记住那些吗?)在每个卷上都有范围,例如:

  • A-B
  • C
  • STO-ZYG

我不认为“sto”是该卷中的有效条目。我确实假设“随机过程”将在卷中。

为什么您的代码会有所不同?在您的情况下更有针对性,即使'5'可能不是有效代码,您案例中的范围也可能'5ZZZ''5'

而且,您的规则最终可能超出范围。也许一些主要代码的所有次要代码都以“5”开头,以“Z”结尾。

我对范围的结论是不需要外键关系。

那就是说,还有一个问题,你可能想要处理。什么阻止代码在多个范围内?我怀疑你需要一个触发器来强制执行这条规则。