我正在设计一个具有以下要求的数据库:
这种结构可能是:
组织
- OrganizationId INT IDENTITY(1,1) NOT NULL PRIMARY KEY
期限
- TermId INT IDENTITY(1,1) NOT NULL PRIMARY KEY
- OrganizationId INT NOT NULL REFERENCES Organization(OrganizationId)
SurveyType
- SurveyTypeId IDENTITY(1,1) NOT NULL PRIMARY KEY
- OrganizationId INT NOT NULL REFERENCES Organization(OrganizationId)
SurveyForm
- SurveyFormId INT IDENTITY(1,1) NOT NULL PRIMARY KEY
- SurveyTypeId INT NOT NULL REFERENCES SurveyType(SurveyTypeId)
- TermId INT NOT NULL REFERENCES Term(TermId)
该结构与单个代理主键的流行强调保持一致。但是,该结构会牺牲数据完整性,因为SurveyForm
记录很容易从TermId
个SurveyTypeId
获得Organization
或OrganizationId
。
为了解决数据完整性问题,您似乎必须添加(OrganizationId, SurveyTypeId)
并在复合键(OrganizationId, TermId)
和{{1}}中使用它。在这个例子中,这是可以容忍的,但随着模式变得更加完整,复合密钥大小会增加。
所以我的问题是,人们现在通常如何处理这个问题(大多数在线参考是从2008年开始,当时我认为可能存在不同的数据库设计问题)?作为必然结果,何时可以将外键添加到表中以减少为常用表达式连接的表的数量?
答案 0 :(得分:0)
我认为可以采用一种方法来避免循环引用,首先是通过定义谁真正依赖于谁以及删除多余的依赖项。
问题是...... Organization
是否允许Term
随机关联到Survey
,而不关心任何Organization
关联?我想知道Term
是否真的需要直接或间接地通过Survey
与Organization
相关联。例如,如果Term
无法与Organization
的{{1}}无关联的Survey
关联,那么组织 - 期限关系就没用了,如果它反之亦然,那么不需要Organization-SurveyType
答案 1 :(得分:0)
从学术上讲,您可以沿着两个谱系迁移组织密钥。毕竟,这只是4个字节:
create table dbo.Organization (
OrganizationId INT IDENTITY(1,1) PRIMARY KEY
);
go
create table dbo.Term (
TermId INT IDENTITY(1,1) NOT NULL,
OrganizationId INT NOT NULL REFERENCES dbo.Organization(OrganizationId),
primary key (OrganizationId, TermId)
);
go
create table dbo.SurveyType (
SurveyTypeId int IDENTITY(1,1) NOT NULL,
OrganizationId INT NOT NULL REFERENCES dbo.Organization(OrganizationId),
primary key (OrganizationId, SurveyTypeId)
);
go
create table dbo.SurveyForm (
SurveyFormId INT IDENTITY(1,1) NOT NULL,
OrganizationId int not null,
SurveyTypeId INT NOT NULL,
TermId INT NOT NULL,
primary key (OrganizationId, SurveyTypeId, TermId),
foreign key (OrganizationId, TermId) references dbo.Term (OrganizationId, TermId),
foreign key (OrganizationId, SurveyTypeId) references dbo.SurveyType (OrganizationId, SurveyTypeId)
);
go
这些表肯定违反了一些NF,我不记得哪一个,但我确定你可以自己处理它。
虽然这种设计方法几乎可以被视为仓库的必需品(特别是如果您汇总来自不同来源的数据),我绝不会推荐它用于任何真实的OLTP。更简单的解决方案是: