Database 完全强制执行数据模型或不完全强制执行数据模型

Database 完全强制执行数据模型或不完全强制执行数据模型,database,sql-server-2005,database-design,Database,Sql Server 2005,Database Design,: 考虑以下逻辑数据模型: *有多家公司 *每个公司都有许多项目 *每个项目都有许多任务 *每个任务都有一个状态,从预定义状态的全局列表中选择 假设我们决定公司、项目、任务和状态的主键都是Identity(自动编号)列,因为我们希望为这些表自动生成主键 基本上,我们有4个表: 状态(主键:状态ID) 公司(主键:公司ID) 项目(主键:ProjectID,FK:[公司].CompanyID) 任务(主键:TaskID,FK:[项目].ProjectID[状态].StatusID)。 现在,请允许

:

考虑以下逻辑数据模型:
*有多家公司
*每个公司都有许多项目
*每个项目都有许多任务
*每个任务都有一个状态,从预定义状态的全局列表中选择

假设我们决定公司、项目、任务和状态的主键都是Identity(自动编号)列,因为我们希望为这些表自动生成主键

基本上,我们有4个表:
状态(主键:状态ID)
公司(主键:公司ID)
项目(主键:ProjectID,FK:[公司].CompanyID)
任务(主键:TaskID,FK:[项目].ProjectID[状态].StatusID)。

现在,请允许我补充一点。假设每个任务的可用状态不是全局定义的,而是在公司级别定义的。也就是说,每个公司都有自己的状态列表,可以为其分配任务

这意味着状态表现在需要对companys表进行外键引用(以指示每个状态所属的公司):

公司(主键:公司ID)
状态(主键:StatusID,FK:[公司].CompanyID)
项目(主键:ProjectID,FK:[公司].CompanyID)
任务(主键:TaskID,FK:[项目].ProjectID[状态].StatusID)。

我们是否需要对此数据模型进行任何其他更改?或者仅仅向状态表中添加一个CompanyID列就足以促进此更改吗?请记住,我们的目标始终是尽可能使用主键和外键约束实现完全引用完整性

嗯,有一个问题:

此数据模型中的任何内容都不会阻止我们为未为该任务的母公司定义的任务分配状态。在目前的限制下,我们无法实施这一点。我们的物理数据模型有缺陷

这很容易修复,但只能通过违反“所有表只需要一个标识主键”规则来实现

首先,请记住:仅仅因为标识列是唯一的,并不意味着该列不能是主键的一部分

他接着指出如何使用组合键来完全强制和约束数据模型,如下所示:

公司(主键:公司ID)
状态(主键:CompanyID,StatusID,FK:[公司].CompanyID)
项目(主键:CompanyID,ProjectID,FK:[公司].CompanyID)
任务(主键:TaskID,FK:[项目](公司ID,项目ID),[状态](公司ID,状态ID))。

长期以来,我一直热衷于全面实施/约束我的数据模型,然而,我经常发现自己处于类似于上述情况的情况下,我遇到了一个十字路口:

完全执行或不完全执行

明显的缺点是设计过于复杂

现在,我知道不一定有“正确”的设计,但对于这样的情况。。我正在寻找最佳实践方面的反馈

此设计的优点、缺点和总体思路,还是全面实施您的数据模型设计?


**请注意,这个问题可能会引发一场争论,即在实施数据模型(数据库或应用程序或两者)方面,责任在哪里。为了便于讨论,我认为您的数据模型应该自我强化——请在这个假设下回答**

我将创建一个
CompanyStatus
表,该表介于
Company
Status
之间,并描述哪些状态适用于给定的公司。然后,任务被分配一个
公司状态ID
,而不是
状态ID

这还可以防止您的
Status
表中存在重复的状态-例如,许多公司可以共享相同的关闭状态,这是更好的规范化


因此,不需要使用复合关键点来正确强制约束。我更喜欢使用没有意义的单个自动递增主键(代理键)。这比假设密钥是唯一的(如SSN)更可靠,因为通常情况下可能并非如此,但您必须存储数据,因为应用程序需要它(因此唯一约束在这里没有帮助).

应用程序和数据库层应该强制执行数据模型的规则。这使得在其中一个中更容易发现bug,因为规则应该被另一个加强;将向作者留下评论,但未看到任何评论选项这是正确/规范化的设计,而不是问题中列出的设计,尽管在任务表中使用StatusId即使不是更好也可以(CompanyStatus仅用于筛选初始分配)我不会对项目做同样的事情,除非多个公司可以与同一个项目关联,而我不是从需求中得到的。我确实理解其基本前提,即您可以使用复合键来获得比代理更好的完整性。这是设计模型时要考虑的问题;个人我还没有找到一个我决定走这条路线的机会——我怀疑在查询中错误键入冗长的组合键比丢失代理键可能给您带来的约束更容易出错。添加CompanyStatus表将允许您拥有一个来自一家公司的项目和一个状态的任务来自另一家公司。不过,除了这一点之外,我真正想了解的是在全面实施数据模型方面的最佳实践。