使用触发器强制数据完整性-冗余



我有一个通用的DB设计问题。

我在数据库中有一个表,其中某个字段在插入时应始终具有值0。将此字段更改为0以外的任何值都涉及某些操作,这些操作是通过更新触发器强制执行的。值为0但没有执行适当的业务规则的记录是无用的数据。

我正在考虑在插入时创建一个触发器,而不是触发器,以强制执行不能向该表中插入除0以外的任何值的记录。这并不是真正必要的,因为用户只能通过存储的proc访问数据库,而当前唯一的INSERT proc将此值设置为默认值,即0。这也不是一种安全措施,因为在我们的系统中,只有SA是特权用户,如果用户以某种方式获得了SA密码,他们可以为所欲为。

我能想到的唯一用途是确保即使在未来,任何开发人员都不会意外地允许在这个字段中插入值,而不会碰到触发器,这使得它成为一个真正的测试工具。

DBA是如何处理这样的事情的?您是否有特定于测试系统的触发器和约束,这些系统不会部署到生产服务器?您是否将这些触发器保留在生产服务器上,作为强制执行完整性的额外措施?

我会考虑添加一层额外的检查。

如果您设计的系统使所有插入和更新都通过存储过程,那么您就是在说"有一个地方会进行逻辑和数据完整性检查"。如果您开始将检查分散到多段代码中,那么就有混淆的风险。哪些支票进入触发器?哪些检查进入存储过程?当逻辑应该在存储过程中时,为什么会有触发器?

我承认这是一个模糊的边界。使用约束意味着数据库正在进行一些检查。然而,这些都是内置在语言中的,所以任何合理的开发人员都应该能够轻松地理解它们。在这种情况下,将列的默认值设置为0,以便即使在表定义中也清楚地表明它最初应该具有此值。

我喜欢在存储过程中包装插入/更新/删除,特别是允许进行额外的检查和日志记录。另一方面是将存储过程强制作为仅接口来修改表。您可以通过只有一个能够修改数据的用户,并让存储过程在进行更改时模拟该用户来强制执行此操作。

通过触发器强制执行状态机是一种合理的策略。触发器可以访问旧值和新值,并确保诸如"新行必须为0"、"0可以转换为1或2,但不能转换为3"等内容。本质上,触发器确保您不能进行对状态机无效的转换。

这可以作为存储过程之上的一个额外的"断言"层,存储过程实际上决定要进行哪个转换。这种触发器也往往非常便宜,因此没有理由将其排除在生产之外。

在你的情况下,这一切是否合理取决于你的状态机有多复杂——它越复杂,这种策略就越合理

最新更新