标准化所有数据库表上的创建日期和上次更新日期字段是否有意义?


38

我的老板目前正在尝试将一些开发标准应用到我们的团队中,因此昨天我们开会开会讨论了这些标准,在她提出之前,大部分进展顺利:

  • 所有数据库表都将具有一个CreatedDate和LastUpdatedDate列,并通过触发器进行更新。

在这一点上,我们的团队意见分歧。我们中有一半的人认为,在所有工作台上执行此操作是一项大量工作,几乎没有收益(我们从事固定预算项目,因此任何成本均来自公司的利润);下半年相信它将对项目的支持有所帮助。

我坚定地在前阵营。尽管我很欣赏某些外部情况会导致多余的列提高可支持性,但我认为,首先添加列所需的工作量以及维护工作将使我们花费更少的时间进行更多的工作重要的事情,例如单元测试或负载测试。另外,我相当确定这些额外的列会使使用ORM变得更尴尬-请记住,我们主要使用C#和Oracle,但从一开始就对ORM不太满意。

因此,我的问题是双重的:

  • 我在正确的营地吗?我并没有声称自己拥有享誉全球的数据库技能,因此这可能是一件容易的事,而且没有不利的副作用。
  • 您将如何处理有关标准的会议演变为排渣比赛的情况?我如何才能真正卖出该标准不会长期帮助我们?

为什么您说C#对ORM不满意?另外,例如,将[insert =“ false” update =“ false” generate =“ always”]属性添加到NHibernate中这两个列的映射中对我来说似乎并不尴尬,还是我错过了一些东西?
Jalayn

C#+ Oracle对ORM不满意,我们发现NHibernate太笨重(显然,我没有参与那种工具调查)。我可能将C#和Oracle放在了主要问题上。
艾德·詹姆斯

您应该考虑重命名问题的标题,以更符合数据库标准的描述。
maple_shaft

这将如何使时间远离任何事物?对于“外部案例”,您将必须至少执行两次。创建一个工具和一些可重用的类,再也不用担心它了。
史蒂文·埃弗斯

Answers:


27

这是相当普遍的做法,尽管我不会说可支持性是主要好处。这种方法的真正好处是保持审计跟踪。通常,还有一个额外的列,其中包含进行最新更新的用户的用户名。

如果您要处理任何类型的财务或有意义的数据,我相信您已经听说过诸如PCISOX合规性之类的内容。全面的审核跟踪对于满足这些规范至关重要。

免责声明:但是,还有更好的方法来实现数据库审计跟踪> https://stackoverflow.com/questions/1051449/ideas-on-database-design-for-capturing-audit-trails


抱歉,忘了提及,PCI(etc.)合规性不适用,日志中已经有过程审核记录(所有记录都非常彻底)。
艾德·詹姆斯

6
“(一切都记录得很彻底)”是否包括CreatedDate和LastUpdatedDate?如果是这样,也许您可​​以将您的同事引向DRY原则:)
MattDavey 2011年

2
这是一个很好的观点,也许我应该努力寻求一个更高效的日志解析器,我们可以使用它轻松地查询已存档的数据(显然,这些数据是用于审计跟踪的,因此我们保留的时间不超过一周左右,因此值得查询,其余的都存储起来)。
艾德·詹姆斯

3
我认为这种方法不会产生丰富的审计线索……我什至不称其为审计线索
–Jordão

@Jordão我说这是一种常见的方法,但我没有说这是一个好方法!因此免责声明:)
MattDavey

17

前一个参数无效,因为将少量数据库维护的时间戳字段添加到一系列表并不困难。实际上,这是初级或实习生的那种麻木的任务,他们可以在两周的冲刺中轻松地完成这项工作,并有余地。

仅仅因为您不希望应用程序用户修改这些字段,并且因为它们对于维护和调试很有用,并且很少在业务逻辑中使用,可能甚至不需要在ORM中映射这些字段。我在两种方式都做过的商店里工作,坦率地说,我对这两种方式都没意见。

即使在数据库级别实现这种功能所带来的好处,即使被夸大了,也仍然远远超过任何人力成本,而且肯定可能少于项目的集体智慧,这些技术精湛的技术劫持了会议并在史诗般的击打比赛中将其散开。当您计算几个小时的会议对项目生命周期的影响时,您可能不会感到惊讶,因为它们很昂贵。想象一下,所有这些人的集体时薪和福利加起来,这应该给你一个主意。


8
创建一个脚本,将这些列添加到每个表(如果触发器不存在的话)。
JeffO 2011年

3
+1您可以在几天内通过代码轻松生成脚本。如果手动完成,仅需大量工作。
乔恩·雷诺

8

...男人做出的决定性陈述越多,他肯定会犯错误的可能性...-tyler durden

这适用于一揽子“标准”,而在某些表上这可能是一个巨大的胜利,在每张表上,这很可能是无用的噪音,更多的代码需要维护或忘记维护。

这里有一个平衡点,那就是您应该敦促决策者。


8

我完全同意。每个数据库中的几乎每个表都应至少具有2个字段:创建日期更新日期。有很多原因应该放置创建日期和更新日期。出于先前人们所说的明显原因……这是审计。

我已经设计系统和数据库已有25年了,已经为数百位客户服务。没有一个客户端不需要此客户端。

有两种基本方法可以做到这一点:

1-第一种做法是让数据库完成工作并将其直接放入表设计中。我建议这是最低要求。

2-我更喜欢的另一种做法是使用复制工具来解决此问题。几乎没有开销,并且DEV团队没有成本。但是,这些工具很昂贵。另一个好处是,使用这种工具可以更轻松地审核删除过程。如果没有复制工具,则需要创建一个审计表并触发删除操作触发器-我认为这不是一个好习惯。

具有这些字段的另一个好处是始终为任何OLTP系统构建的数据仓库和ODS。没有它,您将无法有效地提取增量数据。否则,您将不得不每天重新加载整个数据库。

输入这两个日期还有很多其他的业务原因,在此我将不再赘述。做功课,我相信在接下来的3-6-12-48个月内,您将很高兴在这两个简单的领域中投入知识。

我已经实施了,通常会尽可能推荐两种解决方案。


5

我们已经在数据库中创建了日期和按列创建,它们极大地帮助了我们跟踪数据问题。如果需要还原,它可以帮助我们在完整的审核表中找到正确的记录(因为我们知道要在很大的表中查找的位置)。她也应该添加一个由列创建和修改的列。确实知道知道谁输入了数据,尤其是在没有全面审核的情况下。

我认为没有哪个企业应用程序不需要某种形式的审核。显然,您的老板认为它只需要相对温和的审核即可。就个人而言,我赞成对包含贵公司所依赖数据的每个数据库进行全面审计(从审计表中还原那2000条不良记录要比恢复备份容易得多),并且如果我有任何财务信息的话,我会要求这样做已经看到这种类型的东西可以帮助捕获欺诈行为的人们。所有审核必须在数据库级别进行。

这些数据如何提供帮助?首先,它缩小了查找旧数据(修订版)的时间,并且可以帮助您查看输入数据时程序的哪个版本处于活动状态。因此,如果您知道已在2011年7月6日上线的2.3版中解决了该问题,然后在8月7日插入记录时发现了相同的问题,则可能您的修复效果不佳。如果您需要还原到旧数据,它将告诉您如果没有完整的审核,则可以在哪个版本的备份中找到旧数据。

开发人员似乎很少认为数据必须随着时间的推移进行维护,并且不良数据需要由某人修复。对于我们中那些必须做的事情而言,拥有这样的事情可能会非常有价值。您的老板是对的,尽管我认为她在审计方面做得还不够。只需要解决一个非常严重的问题即可解决,以证明添加这些列和触发器所需的时间非常短。


我希望看到人们有效地对他们的修复程序进行单元测试,而不是尝试通过数据库检查来对其进行验证,但是我很感谢您的观点。但是,我不知道你提出的观点也适用于每个表中所有的数据库,甚至连参考表等
埃德·詹姆斯

单元测试与审核是分开的。我提到它可能会捕获一个错误,因为我已经看到它即使在进行单元测试时也会发生,因为存在未经测试的边缘情况。它还可能指出该数据是在漏洞修复之前输入的,然后您可能需要查找其他也需要修复的数据。或者只是知道这是2016年6月6日通过导入输入的数据,它将帮助您查看问题是否出在您的导入上,或者是导入文件中的数据有问题。这比浏览一年之久的每日导入文件要容易得多。
HLGEM

4

由于可以编写脚本并将其应用于您将要创建的每个数据库,因此工作量很小。将列与触发器一起添加到所有表中。您只需要记住在构建时运行它即可。

根据客户的需求,您可以让他们付费以将其集成到您认为合适的应用程序中。许多人喜欢在记录上查看其他信息,例如谁在上一次创建/更改记录以及何时更改了记录。无需向所有人发送电子邮件以查找或被欺骗。您不需要每次有人查看记录时都查询日志。

将其放入数据库中并以防万一,并不是很困难,并且可以让您付费利用这些字段的其他功能,或者只是为您提供有关使用该系统的客户端数量的一些反馈。


客户尚未就​​此主题发表任何意见(据我所知),并且可能对我们的新标准推动力一无所知,因此,我非常希望他们对支付任何集成费用不感兴趣;)但是,如果稍微依赖“可能”来发展我通常的开发方法,那么“可能会让您负责”是一个很好的论据。
艾德·詹姆斯

1

这将是一个相当琐碎的实现(可能总共需要1到3天),因此我认为它在整个生命周期内将为您的应用程序增加多少价值。

首先,需要使用alter table语句来添加列,alter表都将是相同的(表名除外),因此您可以编写脚本以编写代码为所有需要的表生成alter SQL语句。必须允许NULL来考虑现有数据并检查列是否存在,以便它可以重新运行。

其次,对于列,使用默认值,如GetUTCDate()(SQL Server,Oracle可能有所不同)解决了insert上的任何编码添加问题,因此无需为任何inserts语句更改代码库,因为默认值为用过的。

数据更新(对最后修改的更改)可以通过更新触发器来解决。同样,此触发器在所有表中几乎都是相同的,因此该触发器代码(SQL)也可以是为任何现有表生成的代码。

可能会有很多sql脚本代码(取决于有多少个表),但是它是可重复的模式,因此您可以通过查看现有的数据库模式进行代码生成。


我担心使用像这样的大型方法可能会对新表造成长期维护问题,或者(甚至更糟)您必须创建一个存储程序,该存储程序扫描每个表中的某些命名列,然后生成DDL脚本添加它们(如果缺少),这听起来像一场维护噩梦!
艾德·詹姆斯

如果这是一个标准,则希望制作新表的开发人员遵循该标准。否则,是的,噩梦。该方法是使现有模式达到最高速度,同时确保开发人员有责任遵循该标准。
乔恩·雷诺

我认为该评论中的关键词是“希望”,我不确定我是否相信每位新开发人员自己的志愿活动都会发生什么!
艾德·詹姆斯

2
@Ed-同意,不信任,这就是代码审查的目的!:)
乔恩·雷诺
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.