自从接触资料库开始,我就看到几乎所有人都会在表里添加创建时间和更新时间这两个栏位,在某些对时间敏感的记录中这当然很必要。但是,我不明白的是为什么大家要费时间费精力在所有的表里添加这两个栏位,如果是让资料库管理系统和orm自动添加也还好,仅仅是在表设计的时候添加两个栏位,但是很多软体中会在逻辑代码里插入这两个栏位。令我疑惑的是,几乎我接触到的程序都只是写入这两个栏位,却没有见过这两个栏位具体发挥作用。那么,是什么原因让大家养成了这样的习惯?或者说,在所有的表里都添加这两个栏位是出于什么考虑?这样的习惯带来的回报真的符合它的投入吗?


资料库应用,可以分成两种, OLTP 和 OLAP.

这两种应用虽然在设计模式上有所不同,其实是作为一个应用的整体。孤立地看待各自的设计模式,必然造成疏忽,以至于返工重构。

尤其 OLAP,对于 OLTP 的设计要求极高。举例来说:

1)要求数据的完整性:订单的时间链,缺了一部分就会被定为无效;

2)要求数据的一致性:订单的单价,每个单价都有一个作用时间,缺了时间,双11统计无效;

3)要求数据的纯洁度:一份表达同个主题,属性的数据,不能散落在各个引用表中

当把 OLAP 与 OLTP 联合起来的时候,ETL 逻辑的准确性就显得十分重要。除开使用业务逻辑单独生成批次跑数据,没有比加时间戳更好的控制增量跑批的效率。

当然纯靠时间戳跑批,也会带来数据的不完整性,比如OLTP的数据经常会有手工更改的情况,此时时间戳就变得不可信了。

综上,要不要加 CreateDate,UpdateDate,CreateBy,UpdateBy 完全取决于业务系统和分析系统的需求,并不是都要加,加了有个参考,方便后续系统集成,但加了就会有维护成本。


看栏位的名称就大概知道,这两个栏位是跟业务逻辑有关系的。所以不可能是「几乎所有表」都有。如果是为了跟踪对记录的创建和修改,那么光这两个栏位也是不够的。比如一个用户表,update_at只能跟踪最后一次修改用户信息的时间。一般都还需要另一个表来发挥时间线的作用,已日志的形式记录每次用户修改操作,以及操作的内容


很多回答说这是业务逻辑需要,业务逻辑不关心的表可以没有。但我可以明确的说,任何表都应该有这两个栏位——除非你能保证每次更新的所有代码都没有bug。

如果某个版本的代码有bug破坏了一部分记录的正确数据怎么办?直接找一个上线前的版本恢复么?很显然大部分情况是不可能的。如果能计算/恢复出正确的数值,可以用这两个栏位作为条件更新回正确的数值。即使找不回正确值,也可以打上标记将来做后续处理补救——假设是一张客户信息表的某个栏位错了,这期间新注册或者修改过资料的客户资料都受到了影响,可以通过电话回访或者下次客户登录的时候让受影响的客户补充,而不受影响的客户自然就不需要做这样的操作。


因为设计的时候偷懒了,这两个栏位对部分内容有用,对大部分其实是没用的.但是设计的时候没有考虑清楚哪里需要这两个栏位,就统一加上了.


这不是必要的。

无用栏位会浪费空间、性能,从而积少成多影响系统性能。

这类设计大多影响轻微,但遇到性能问题时,它们就成了压垮骆驼的每一根稻草。

设计动机应当问设计者。但我私以为这些log应该单独做。


updatedAt 在一些情况下可以作为乐观锁使用


其实还有有必要的,出问题了追责的时候就会觉得有用了


这两个栏位就是表示创建时间和更新时间的。

资料库设计的目的是通用性。设计资料库很容易做到自动为每张表添加这两列。但副作用就是资源的浪费。你看到几乎所有人并不能代码这两个栏位是通用的。

对于update_at栏位,其实Oracle已经有了,你可以查看一下Oracle的ORA_ROWSCN的伪列介绍。类似于innodb这样的mvcc设计,如果版本号是使用时间戳表示,通过伪列技术就很容易实现了。


倒不一定是为了追责,不然至少还得来一组CreatedBy/UpdateBy,而是出数据问题的时候多一个有助于查找原因的参考信息。多两个栏位成本不大,作用也不见得大,但也许就有那么一两次用得上的时候。


为了出现问题能查出是什么时候的问题,对于关键业务,会有类似cdc的日志表,记录每一次变更,对于非关键性业务这两个栏位个人认为只是用来查一下记录时间。我见过的业务系统除非做etl否则不是所有表都加这两个时间。


并没有哪里规定必须加上这两个栏位,它们通常是资料库框架自动添加和维护的。也就是说它们并没有你所说的「投入」。既然没有,是否有值得的回报也不重要了。

有些框架是默认添加的,你可能需要主动设置某个属性值为 false 来特意避免这两个栏位。有些框架不默认,但是提供了快捷添加的途径,并且在示例代码中使用了它们(例如 Ecto 的 timestamps,顺便 created_at 叫 inserted_at)。

以上言论对很多知名框架都适用,不限定程序语言,毕竟互相借鉴再普遍不过了。

这就导致了,有的人可能不知道怎么去掉这两个栏位,而有的人学习过程中模仿文档中的示例代码,跟著就添加上了。毕竟留著也不麻烦,也确实没什么害处。

所以你问的有什么考虑之类的,也许压根就没有那么「多虑」。如果说这两个栏位纯粹是自己手动添加和维护的,那可能真的有考虑,但也可能只是单纯的对知名框架的模仿。


如果说作用,排序什么的就不说了。就算你不认为它们有其它用处,为了排序你还是会添加,毕竟按时间排序是很普遍的。

即便某些数据不用按时间排序,甚至压根不用排序,其实这两个栏位也有作用。那就是跟踪和追溯历史行为,常发生在排查异常情况和调试的时候。

但你若认为真的没必要,你不添加更没害处。


OLTP中每个表都这么做,基本上是为了debug,以及未来可能的ETL中用到,比如基于时间的增量同步.

而OLAP就要看使用的模型了.如果采用维度建模,那就看应用了.但是如果采用data vault模型,每个表都必须加load time,除此之外还有失效时间,数据来源.这是必要的栏位.因为在这种模型中,数据都是基于时间来存储.


laravel 也默认表里会有这两个栏位,但是业务不需要的话就可以关掉。


推荐阅读:
相关文章