使用触发器而不是外键强制引用完整性

问题描述:

我正在为基于Web的应用程序构建一个新数据库,并发现我经常必须在模型的灵活性和有意义的外键之间做出决定,以实施参照完整性。使用触发器而不是外键强制引用完整性

有一对夫妇设计的方面,导致我对写作触发做什么FKS通常会做:

  1. 模型的部件使用数据表的Class Table Inheritance Pattern和一些有对象ID其基础类型应限制为对象类型的一个子集。这在触发器中很容易实现,但在FK中不可能不会使数据模型复杂化。

  2. 该数据库具有非常灵活的参考数据模型,允许最终用户使用新字段自定义其数据库实例(每个客户端都有自己的数据库),并扩展常用字段的预定义值列表。起初,我有一百个具有完全相同架构(ID,名称)的小表,但已经将它们整合到一个表(FieldID,ID,Name)中。再次,这将是非常简单的触发器来检查,但不可能在FK

其他一些细节:

  • 正如上面提到的,每个客户都会有自己的数据库
  • 副本
  • 每个数据库的大小不可能很大。也许某处10 - 50 GB范围
  • MS SQL 2008

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

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

+0

刚问... http://*.com/q/3981735/65223 – 2010-10-20 20:03:37

+0

如果您开始使用[快照隔离],则可能会出现一个潜在的错误(http://sqlblog.com/blogs/hugo_kornelis/archive/ 2006/07/26/134.aspx) – 2010-10-20 20:54:15

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

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

+0

我同意这将是一场灾难,他们不能改变结构,只能添加参考数据。参考数据表只是一个关键/值对的大型存储库。我允许用户添加其他对以用于报告。新对必须是常见值的子类型,因此它不是完全敞开的。 – 2010-10-20 18:08:00

+0

@Mike Forman说:“我允许用户在报告中添加额外的对。”您是否为这些报告编写了查询?如果不是的话,你应该考虑在继续这个模式之前尝试去做这件事。如果您已经为这些报告中的任何一个编写了查询,您是否使用任何大量数据运行它们? – 2010-10-20 18:17:59

+0

@KM - 还没有,我在这个过程中还很早。我正在考虑在引用表中使用新的hierarchyid数据类型,以便我可以检查父或父级的父级,或者在需要父级时只创建并维护一个额外的键/值。我知道这里有一些丑陋的折衷,我试图决定他们是否值得额外的灵活性。该模型确实解决了很多“我们应该把它放在哪里?”问题,但如果有必要,我愿意回到制图板。 – 2010-10-20 18:50:42

从您的描述来看,触发器随着时间的推移会变得越来越复杂,并且最终会成为噩梦来维护。

在我的职业生涯中,我不得不维护这种“ObjectId”数据模式,而我的经验一直是负面的。随着时间的推移,维护变得非常痛苦,执行有意义的查询变得非常复杂。基本上你会做的是放弃一个“真实”的关系模型,用于某种元数据模型。

这似乎违反直觉,但维护一个适当规范化的关系模型,即使是具有多个表的一个模型,通常比维护元数据模型更容易。所有这一切说,如果我要去“ObjectId”路线,我会考虑在我的应用层中强制执行完整性,而不是使用触发器。不利的一面是它可能会在系统中获取不良数据(逻辑错误或人们通过SSMS手动输入数据)。但是维护可能更易于管理。

没有任何关于您的应用程序的逻辑或表结构的想法,我不能说比我说的经验是,随着数据模型的灵活性增加,查询的复杂性会增加。这也带来了性能上的痛苦。

此外,关于外键,我发现这...

原因定义外键约束

  • ,他们的身体,防止数据完整性问题定义业务 您的数据库。 (例如,数据库 在没有现有订单标题的情况下阻止订单项的创建 )
  • 它们通过显示所有数据如何与 彼此相关,从逻辑上记录业务。对于刚刚参加 组织的人来说,这使他/她能够很好地了解 业务的运作方式。 (例如,每个订单 采取必须有一个有效的客户 分配)
  • 外键是SQL Server本机,并旨在防止 数据完整性问题。业务逻辑 开发人员不应该在 业务中验证表 的关系。
  • 如果已正确定义和编制索引,则SQL查询引擎可以利用它们生成 极其高效的查询计划。

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

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

您应该看看NoSQL和结构化数据存储。

+0

请参阅http://en.wikipedia.org/wiki/Nosql – 2010-10-20 18:31:24