自從接觸資料庫開始,我就看到幾乎所有人都會在表裡添加創建時間和更新時間這兩個欄位,在某些對時間敏感的記錄中這當然很必要。但是,我不明白的是為什麼大家要費時間費精力在所有的表裡添加這兩個欄位,如果是讓資料庫管理系統和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 也默認表裡會有這兩個欄位,但是業務不需要的話就可以關掉。


推薦閱讀:
相關文章