數據庫表設計太劣質,被領導瘋狂diss
本文轉載自微信公眾號「Java極客技術」,作者鴨血粉絲。轉載本文請聯系Java極客技術公眾號。
在大家開發的時候,很多時候不是說,有人告訴你已經完全的設計好數據庫了,也沒有專門的人去管理數據庫表設計這塊的內容,而阿粉的朋友就是這么悲催,接手了公司一個同事的一個比較重要的功能,而阿粉的朋友也沒有重新進行設計,于是就出現了這樣的一幕。
你設計的這是啥?
領導:你數據庫設計的軟刪除呢?Delete 就直接給我刪了?萬一到時候用戶反悔了,想查詢某項數據怎么辦?
我:........(內心OS:這特么不是我設計的好不)
領導:你趕緊給我加上這個,我給你講講需求,你看他之前做了多少了,把沒做的功能都給我補上。
我:.........好的(內心OS:我擦,他做了這么久的功能就做了這么一丟丟,你讓我抓緊時間做完,你是傻子么?)
領導:你看這,兩個表的關聯字段,竟然不是相同類型的,你不用相同的名字就不用吧,你類型不一樣,怎么能行,你趕緊去統一一下。
我:.........(這明明不是我設計的表好不好,這種低智商的行為,是我能干出來的事情么?)
但是阿粉朋友在向阿粉抱怨的時候,就表示心態已經被影響了,明明不是自己的鍋,結果這鍋到最后全都是自己來背,不過想想也是,畢竟如果要是這個功能非常好做的話,那同事為啥辭職。阿粉接下來就說說這個數據庫表的設計,到底是怎么設計才能更好呢?
數據庫表設計遵循原則
數據庫表設計范式
(1). 第一范式(確保每列保持原子性)
這是什么意思呢?你如果去百度上搜索,結果就是所有字段值都是不可分解的原子值。就這話,云里霧里的有點難理解呀,這種情況我們就得自己去想想有沒有什么現實生活中的案例,比如說,我們在保存某些地址信息的時候,一般我們都是采用,省市區,然后再加上具體的位置來表示完整的地址,很少有人會在數據庫中直接設計一個地址的字段,再比如我說我們設計商品的時候,都是商品,數量,價格,而不是設計成商品1,商品2,商品3,數量1,數量2,數量3.
而數據庫的第一范式也就是 1NF,實際上不單單是保證每一列的原子性,還有如果兩列的屬性相近或相似或一樣,盡量合并屬性一樣的列,確保不產生冗余數據。
這就是阿粉上面說的那個商品的案例。
(2).第二范式
在一個數據庫表中,一個表中只能保存一種數據,不可以把多種數據保存在同一張數據庫表中。
每一行的數據只能與其中一列相關,即一行數據只做一件事。只要數據列中出現數據重復,就要把表拆分開來。
上面這句話感覺好像有點多此一舉的樣子,相同的數據信息在一般人的設計中,是不會出現在同一張表中的,因為畢竟如果某些字段一直是重復的,數據量多不說,關聯的時候也會出現左也不行,又也不行,就會出現寫SQL出現各種問題的情況。
(3).第三范式
數據不能存在傳遞關系,即每個屬性都跟主鍵有直接關系而不是間接關系。阿粉之前接收過一個項目,就是出現了 A 指向 B,B 指向 C,加入說我們現在有一張訂單表,我們訂單表中肯定要有人員的信息,而我們又會有一張人員信息表中的Id與訂單表中的人員信息對應,這時候,訂單表中就盡可能的不要存在人員的其他相關的信息了,比如說姓名,身份證號,等等信息。
而這時候,我們在獲取訂單信息的時候,直接通過當前用戶的ID,就可以查詢出所有對應的訂單,那些所有的人員信息全部都包含在了人員信息表中。
說到這里,阿粉實際上想說,數據庫三范式,只是說是一個原則,而不是非要遵守的原則,因為有些時候,很多在建表的時候,都是根據我們的需求來進行制定。
范式也有優缺點:
設計數據表的時候,其實范式的優點很明顯,避免數據冗余,減少維護數據完整性的麻煩,減少數據庫的空間,數據變更速度快
但是缺點也是一樣的明顯,按照范式的規范設計的表,等級越高的范式設計出來的表數量越多,獲取數據時,表關聯過多,性能較差。
阿粉之前見過一個很早之前的項目,一個醫療系統,設計的表大概超過有2000個表,阿粉當時都滿臉的震驚。
據說是一個很早之前的程序員設計的,當時是嚴格遵守了范式來進行的數據庫的設計,結果可想而知。一個SQL查詢,關聯那么多的表,效率能高到哪里去呢?
學會通過需求來進行定制
大家還記得阿粉之前寫過的用UUID生成主鍵,被diss么?
比如之前的對比,數據庫自增,雪花算法生成ID,和UUID生成ID,這三個的對比,結果100w條數據,最終勝出的還是雪花算法,大家對這個有興趣的可以去看一下這篇文章。
為什么說要學會通過需求來進行定制,因為首先我們要清楚,你寫的東西,最后實際的落腳點,都是需求,實現了這個需求,在不出現任何意外的情況下,永遠都是需求放在第一位,如果你把一個簡單的一對多的關系,非要拆分成一個多對多的關系,這完全就是多此一舉的事情。
而這種通過需求來進行定制的,實際上就可以稱之為反范式。
而反范式設計同樣的也是優缺點明顯,業務場景中需要的數據幾乎都可以在一張表上顯示,數據冗余了。
但是它提高了業務響應的時間,現在為什么有些中間件的存在,就是因為隨著公司業務的拓展,數據量的增多,有時候一個表中的數據超過百萬,甚至千萬,當你寫一個NOT IN 的時候,你就會發現,一秒,兩秒,三秒....時間就這么過去了。
阿里開發手冊
實際上阿粉之前也專門研究過一段時間的阿里開發手冊,比如:
【強制】:表達是否概念的時候,必須使用is_xxx的方式來進行命名,數據類型使用unsigned tinyint (1,表示是,0表示否)
比如如果你在數據庫的表中設計軟刪除的概念,你選擇使用is_delete 還是會選擇使用 deleted 這種,實際上百分之60以上的是會使用 is_delete,而設計這種 deleted 的,一般很多都是剛入行不久的年輕人,對字段設計沒有什么概念的。
【強制】:表名稱不使用復數名詞,比如說我們的活動Activity,你如果把它設計Activities,當你在建立實體類的時候 Activity 和 Activities 是不是感覺就不一樣,第二個看著就總是有些難受。
大家如果有興趣的,可以在公眾號回復 阿里 獲取泰山版 阿里巴巴開發手冊。
關于數據庫設計,你還想知道些什么?