我认为您的关系没有问题。我认为问题在于,通过对每个表使用代理键(即Ids),结果数据库无法防止插入其部门属于一个公司而分类属于另一公司的工人,反之亦然。理解这一点的一种好方法是使用ER图表工具可视化架构。我将使用免费下载的Oracle Data Modeler工具。
ER图
就目前而言,您可能有两家公司-say IBM
和Microsoft
。 IBM
可以有一个Software Development
部门,而Microsoft可以有一个Desktop Software
部门。IBM可以有一个Software Engineer
分类,而Microsoft可以有一个Software Developer
分类。现在,因为你有一个代理键Department
和Classification
,这其实Software Development
是一个IBM
部门,Desktop Software
一个Microsoft
部门失去了未来孩子的关系。的情况也是如此Classification
。因此,很容易意外分配Harlan Mills
,谁是部门的IBM
雇员Software Development
,其类别Software Developer
是Microsoft
分类!同样,可以给工人正确的分类和错误的部门!这是显示第一个示例的图:
1个ID代表IBM
,而2个ID代表Microsoft
。我已经以红色突出显示的场景Harlan Mills
和Bill Gates
被分配到错误的部门,由相关的200分类ID,反之亦然10部门ID显现。
解决方案
那么,有什么选择可以阻止他发生呢?有两个直接选择。首先是要认识到,通过为每个表使用代理键,此问题就存在了,并引入了其他编程来验证它不会发生。可以在应用程序中完成此操作,但是如果在应用程序外部可能发生插入和更新,则仍然可能发生错误的关联。更好的方法是创建一个在员工的插入和更新时触发的触发器,以确保指定部门与分配的类别属于同一公司,如果没有插入或更新,则触发该触发器。
第二种选择是不对每个表使用代理键。而是仅对Company
基本表且没有父表的表使用代理键,然后创建与和子表的标识关系。现在,和表的PK 加上序号或名称以区分它们。然后,从关系和到也成为因此的PK 成为,再加上(我使用在该实例中的序列号),再加上。结果仅存在于表中。现在无法分配一个Department
Classification
Department
Classification
Company Id
Department
Classification
Worker
identifying
Worker
Company Id
Department Number
Classification Number
one
Company Id
Worker
Worker
一个Department
在一个Company
和一个Classification
在另一个Company
。
为什么这不可能呢?这是不可能的,因为该模式实现之间的参照完整性Worker
和Department
和Classification
。如果尝试在一个和另一个的Worker
a Department
中插入a ,则对应的父表中不存在的组合将触发参照完整性违规,并且插入将不起作用。Company
Classification
这是第二个选项的实现的更新图:
首选选项
在两个选项中,出于两个原因,我绝对更喜欢第二个选项-使用标识关系和级联键。首先,此选项无需其他编程即可实现所需的规则。开发触发器并非易事。必须对其进行编码,测试和维护。确保触发逻辑是最佳的,以免影响性能也不是一件容易的事。《数据库专业人员的应用数学》一书提供了有关这种解决方案的复杂性的许多详细信息。其次,这些规则暗示一个部门和一个分类不能在的上下文之外存在Company
,因此该架构现在可以更准确地反映现实世界。
这是一个很好的问题,因为它确切地说明了为什么仅假设每个表都需要代理键是一个坏主意。 Fabian Pascal在此主题上有一篇出色的博客文章,表明从数据完整性的角度来看,代理键不仅是一个坏主意,而且还可能导致某些检索速度变慢在物理级别上,恰恰是因为不需要键,而键被正确地级联,就不需要连接。这个问题揭示的另一个有趣的话题是,数据库不能确保插入其中的所有数据相对于真实世界都是准确的。相反,它只能确保插入其中的数据与声明的规则一致。在这种情况下,我们可以通过使用级联键方法来确保 DBMS可以Worker
就给定给定Company
a的a Classification
和给a Department
相同的规则保持数据一致,从而做到最好Company
。但是,如果在现实世界中Microsoft
有一个部门被称为,Desktop Software
但是数据库的用户断言该部门是Software Development
DBMS只能做一个事实,它什么也不能做。