MySQL進階系列:數據庫設計中的範式究竟該如何使用

這是我參與8月更文挑戰的第1天,活動詳情查看:8月更文挑戰mysql

 這篇文章主要爲了說明規矩要遵照,可是也別這麼死板,要知道因場景不一樣而變化。瞭解各自的優缺點,在不一樣業務中根據需求選擇使用。 sql

範式-反範式000657@2x.png

咱們在項目上進行數據庫設計的時候要求遵照三範式,爲何會約束三範式呢:爲了減小數據冗餘。數據庫

回憶下是哪三範式:緩存

  1. 全部屬性具備原子性,列不可分割。markdown

    例如家庭地址(xx省xx市xx地址),家庭地址做爲字段就是非原子的,能夠拆分紅字段省份,城市,地址。數據庫設計

  2. 在第一範式的基礎上,要求全部非主鍵字段徹底依賴主鍵,不能產生部分依賴。post

    一個數據庫表中,一個表中只能保存一種數據,不能夠把多種數據保存在同一張數據庫表中。網站

  3. 在第二範式的基礎上,保證每列都和主鍵直接相關,不存在傳遞依賴spa

    表中的字段和主鍵直接對應不依靠其餘中間字段。傳遞依賴:A--->B--->C。設計

範式

優勢:

  1. 範式化的更新一般比反範式更快。
  2. 當數據較好的範式化後,就只有不多或者沒有重複數據。
  3. 範式化的表一般更小,能夠更好的放進內存了,因此執行操做也會更快。
  4. 不多有多餘的數據意味着檢索列表數據時更少須要distinct和group by語句。

缺點:

  1. 一般須要表關聯,複雜一點的查詢語句可能至少須要一次關聯,也可能會使得索引失效。

阿里開發手冊中規定表join關聯不能超過3個,主要緣由就是數據量大的時候join查詢很是慢,可是也不必定不能關聯多個,具體問題具體分析,數據量少的時候多張表關聯也沒影響的。

反範式

優勢:

  1. 數據都在一張表中,能夠很好的避免關聯。

    若是不須要關聯,則對大部分查詢最差的狀況---即便表沒有使用索引,是全表掃描。當數據比內存大時,可能比關聯要快得多,由於這樣避免了隨機I/O(全表掃描基本上是順序I/O,但不是100%的和引擎有關).

  2. 單表能夠更有效的使用索引策略。

缺點:

  1. 表中的冗餘較多,刪除數據的時候容易形成部分有用數據丟失。

混用範式和反範式

實際上徹底範式或者徹底反範式都是理論上的。在實際的項目開發中,基本都是混用的,沒有嚴格的規定。

案例分析:

例A: 假設有一個網站,容許用戶發送消息,並且其中一些用戶是VIP,如今想查看VIP用戶的近10條信息。

  1. 徹底範式化  表設計:user(user_id,user_type)表和message(message_id,user_id,message_text,published)表,published構建索引

查詢sql:

SELECT  message.message_text FROM  message  INNER JOIN USER ON message.user_id = USER.user_id WHERE  USER.user_type = 'VIP' ORDER BY  message.published DESC   LIMIT 10;
複製代碼

上面sql須要表關聯,mysql須要掃描message 表的日期published的索引,對於每一行找到的數據都要到user表檢索是否是VIP用戶,若是VIP只是很小的一部分,這個效率就很低下了。另外一種執行計劃是先從user表開始,找全部VIP用戶獲取並排序,這種可能更糟糕。

  1. 徹底的反範式,須要在message表中存儲user數據,就會存在message數據操做影響user數據的問題。

  2. 混用範式和反範式:修改message表結構增長用戶類型字段user_type, 如:message(message_id,user_id,message_text,published,user_type),這種設計能夠避免徹底範式化帶來的表關聯查詢,也避免了徹底反範式的插入刪除問題(即便沒有消息用戶的信息也不會丟失)。

例B: 若是部分需求是查詢的結果須要排序,從父表中冗餘一些數據到子表更方便設計索引,提升查詢效率。

例C: 對於緩存衍生值也是有效的,若是須要顯示每一個用戶發了多少消息(論壇發帖),每次須要執行一個統計的自查詢計算,其實能夠在user表中增長消息數量的字段,當用戶發送消息的時候更新這個值(須要平衡更新和查詢哪一個更好)。

以上只是爲了說明範式和反範式以及混用範式而舉的例子,可是實際開發中仍是要根據業務來選擇怎麼使用。

在表設計中,使用範式也好,反範式也好,不該該有嚴格的限制,該用哪一種就使用哪一種或者二者結合使用。

mysql進階系列持續更新中

相關文章
相關標籤/搜索