使用触发器而不是外键实现参照完整性

时间:2010-10-20 17:48:12

标签: database database-design data-modeling

我正在为基于Web的应用程序构建一个新数据库,并发现我经常需要在模型的灵活性和有意义的外键之间做出决定来强制引用完整性。

设计的几个方面让我开始编写触发器以执行FK通常会做的事情:

  1. 模型的某些部分使用Class Table Inheritance Pattern,而某些数据表具有ObjectID,其基础类型应限制为对象类型的子集。这在触发器中非常容易,但在FK中不可能,不会使数据模型更加复杂。

  2. 数据库具有非常灵活的参考数据模型,允许最终用户使用新字段自定义其数据库实例(每个客户端将拥有自己的数据库)以及扩展公共字段的预定义值列表。起初,我有一百个具有完全相同模式(ID,名称)的小表,但后来将它们全部合并到一个表中(FieldID,ID,Name)。同样,这对于检查触发器非常简单,但在FK

  3. 中是不可能的

    其他一些细节:

    • 如上所述,每个客户都有自己的数据库副本
    • 每个数据库的大小不太可能很大。可能在10 - 50 GB范围内的某处
    • MS SQL 2008

    这个想法听起来合理吗?还是有一些我没想过的巨大陷阱?我将创建外键的原因是强制数据完整性并防止孤立行。只要完成这一目的,手段就不重要了,对吗?

    编辑:我觉得我应该澄清一点,我不打算用触发器执行所有参照完整性检查。我什么时候可以使用外键。在我的模型中只有几个区域我不能。到目前为止,我很欣赏这些深思熟虑的答案。

4 个答案:

答案 0 :(得分:2)

从你的描述来看,在我看来触发器随着时间的推移会变得越来越复杂,最终将成为维持的噩梦。

我必须在我的职业生涯中维护这种“ObjectId”数据模式,而我对它的体验一直是消极的。随着时间的推移,维护变得非常痛苦,执行有意义的查询变得非常复杂。基本上你要做的就是放弃一种元数据模型的“真实”关系模型。

这似乎违反直觉,但维护一个正确规范化的关系模型,即使是一个有很多表的关系模型,也(通常)比维护元数据模型更容易。

所有这一切,如果我要去“ObjectId”路线,我会考虑在我的应用层强制执行完整性而不使用触发器。缺点是它可以在系统中获取不良数据(逻辑错误或人们通过SSMS手动输入数据)。但是,维护可能更容易管理。

答案 1 :(得分:2)

在不了解应用程序的逻辑或表结构的情况下,我不能进一步评论,而是说我的经验是随着数据模型的灵活性增加,查询的复杂性将会增加。这也带来了性能上的痛苦。

另外,关于外键,我发现了......

  

定义外键的原因   约束

     
      
  • 他们通过防止数据完整性问题在物理上定义业务   你的数据库。 (例如数据库   阻止创建订单项   没有现有的订单标题)
  •   
  • 他们通过展示所有数据的相关性来逻辑地记录业务   彼此。给你的新人   组织,这允许他/她   很好地理解了如何   商业工作。 (例如每个订单   必须有一个有效的客户   分配)
  •   
  • 外键是SQL Server的原生,旨在防止   数据完整性问题。商业逻辑   开发者不应该在   验证表的业务   关系。
  •   
  • 如果正确定义和索引,SQL可以利用它们   服务器查询引擎生成   非常有效的查询计划。
  •   
     

来自http://www.mssqltips.com/tip.asp?tip=1296

答案 2 :(得分:0)

使用触发器实现更复杂的参照完整性规则是可以的,但可能会让新开发人员感到困惑,因此请确保内部文档记录良好。

让客户自定义他们的数据库结构虽然有问题。这很可能会导致维护问题。更好的选择是创建一个可以保存任何数据的通用结构,例如键/值对表。

答案 3 :(得分:0)

您正在使用关系数据库系统来存储一组键值对。这意味着您没有使用关系系统的全部功能。如果您真的认为键值对是存储数​​据的最佳方式,那么您应该考虑使用除RDBMS之外的其他方法。显然,数据库技术与您的数据存储需求不匹配。

你应该研究NoSQL和结构化数据存储。