數據庫雜談之:如何優雅的進行表結構設計

本文首發於知乎專欄,轉載請註明出處 https://zhuanlan.zhihu.com/p/20785905數據庫

數據庫表結構設計做爲後端軟件開發不可或缺的一環,是每一個後端工程師都會經歷的過程。筆者也屢次經歷過這樣的過程,也嘗試過多種不一樣的設計方案,也從一些優秀的框架中學到很多,但並無發現相關的文章對其進行總結。因此本文嘗試把筆者看到的、學到的總結下來,但願對閱讀本文的讀者有所啓發。後端

表結構設計主要有兩個目的,一是讓表結構更加的更具備表現力,作到數據庫表的自描述,減小注釋甚至不使用註釋;二是知足系統效率和擴展性的須要,讓系統性能更好,後期維護更簡單。微信

本文主要探討的是如何優雅的設計表結構,讓人可以直觀的從命名中窺探設計意圖,傳達設計者的設計目的,讓團隊成員達成共識,減小溝通成本。本文不討論表結構設計對性能的影響,也不討論數據庫設計中的範式與反範式設計。本文將從數據庫表的命名和字段的命名兩個方面展開。框架

數據庫表的命名

使用名詞做爲表名數據庫設計

仔細想一想即可發現,數據庫表中存在的全部數據都是現實世界各類操做的結果,它們有的是中間過程結果,有的是最終數據結果。不論怎樣,它們是一份一份沒有任何動做的,靜態的記錄。而表自己就是存儲這些記錄的容器,從這樣的層面理解,表名應該採用名詞的形式是徹底符合邏輯的。性能

好比咱們要設計一個存儲用戶邀請的表,invitation 就比 invite 更加的優雅。翻譯

相關表採用統一前綴設計

咱們知道,大型系統的設計每每按模塊或者子系統進行劃分,一個一個模塊的處理問題,保證模塊間的低耦合,模塊內的高內聚。數據庫表設計也同樣,咱們能夠對相關聯的表採用相同的前綴,使開發人員一眼看上去就知道哪幾個表是相關的。事件

好比對於用戶基本信息表、用戶的詳細信息表和用戶的微信綁定表以下的命名更可取:開發

user
user_profile
user_wechat

字段的命名

本節先介紹幾個比較通用的原則,使得字段的含義更容易理解,描述性更強,以後進行簡單的總結分類,以便讓咱們明白這些原則背後的邏輯。

使用動詞被動形式+描述性後綴

經過前面咱們知道,數據庫表中的全部記錄都是靜態的結果性數據,它是由必定的用戶操做產生的。那麼它是如何產生的?通過什麼樣的操做產生的呢?
在解答以前先看一個例子,下面是一個簡單的 article 表結構:

id: integer
title: varchar
content: text
user_id: integer
create_time: timestamp

這樣的設計自己是沒有問題的,目前用的也不少。這個設計主要的問題是沒有體現出 user_id 與這篇文章的關係,須要通過必定的猜想和思考才能得出。create_time 雖然還比較直觀,但沒有體現出這篇文章實在過去的某個時間建立的。

而後咱們在來看修改後的設計:

id: integer
title: varchar
content: text
created_by: integer
created_at: timestamp

經過把 user_id 替換爲 created_by、create_time 替換爲 created_at,使得咱們更容易理解對應的文章是被指定的人在指定的時間建立出來的,而不須要咱們的多方猜想或者查閱文檔,使得整個表結構的描述性更強。

時間區分當前時間和將來時間

英語中表時間的時候, at 通常跟一個時間點,而 in 有表示在將來的某個時間以內的意思。結合起來,筆者傾向於用 at 表示過去或者如今的時間,而用 in 表示將來的時間。好比日曆中的 event 有開始時間和結束時間的概念,我以爲以下的命名是比較合理的:

starts_at 事件的開始時間,相對 ends_in 它屬於當前時間,採用 _at 後綴
ends_in 事件的結束時間,相對 ends_in 它屬於將來時間,從用 _in 後綴

其餘咱們比較經常使用的好比 created_at、updated_at、expires_in 都屬於這種類型。

使用第三人稱單數

當咱們採用動詞+介詞的時候我更傾向與使用第三人稱單數,由於字段描述的這個實體是單數的,經過使用第三人稱單數,咱們能夠天然語言的方式表達出須要的意思。好比以 event 爲例,翻譯成英語是這樣的:

The event starts at 2016-05-05 12:00:00

徹底符合英語的語法,也表達了咱們想要表達的意思。

區分單數與複數

單數與複數主要是對字段內容的描述,好比通知(notification)有接收人這個字段,若是咱們須要通知可以發送給多我的,那麼 receivers 這樣的字段名稱明顯好於 receiver,由於 receivers 體現了通知能夠發送給多我的這一個事實。

前面從四個原則出發介紹瞭如何讓字段更具備描述性,簡單總結下來我以爲從語義上來講,字段能夠分爲兩種類型:描述性字段動做性字段

描述性字段是對對應數據庫記錄(或者說實體)的補充說明,好比以人做爲實體,那麼人的身高、體重和血壓就屬於這類描述性字段。

描述性字段若是是動詞+介詞的形式,動詞須要採用第三人稱單數的形式,好比 starts_at。而後根據字段的內容,若是內容有多個元素或實體,咱們須要使用複數,不然使用單數形式。

動做性字段不只能對所屬實體進行補充說明,還能對這個實體的所涉及操做有所描述。好比咱們有 article 這個實體, article 的 created_by 和 created_at 就屬於動做性字段,由於它不只表達了 article 的建立者和建立時間這層信息,它還表達了這個 article 是指定的人被建立的,而不是憑空生成的。

2016年5月5日北京

相關文章
相關標籤/搜索