MySQL如何設計數據庫


一、范式和反范式

優秀的庫表設計是高性能數據庫的基礎。如何才能設計出高性能的庫表結構呢?這里必須要提到數據庫范式。范式是基礎規范,反范式是針對性設計。

1.1、范式

范式是設計數據庫結構過程中所要遵循的規則和指導方法

其實范式有很多,目前關系數據庫有六種范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又稱完美范式)。滿足最低要求的范式是第一范式(1NF)。在第一范式的基礎上進一步滿足更多規范要求的稱為第二范式(2NF),其余范式以次類推。一般來說,數據庫只需滿足第三范式(3NF)就行了。但是一般我們就用到前三個范式

第一范式(確保每列保持原子性)

第一范式是最基本的范式。如果數據庫表中的所有字段值都是不可分解的原子值,就說明該數據庫表滿足了第一范式。

第一范式的合理遵循需要根據系統的實際需求來定。比如某些數據庫系統中需要 用到“地址”這個屬性,本來直接將“地址”屬性設計成一個數據庫表的字段就行。 但是如果系統經常會訪問“地址”屬性中的“城市”部分,那么就

非要將“地址”這個屬 性重新拆分為省份、城市、詳細地址等多個部分進行存儲,這樣在對地址中某一 部分操作的時候將非常方便。這樣設計才算滿足了數據庫的第一范式,如下表所 示。

上表所示的用戶信息遵循了第一范式的要求,這樣在對用戶使用城市進行分類的 時候就非常方便,也提高了數據庫的性能。

第二范式(確保表中的每列都和主鍵相關)

第二范式在第一范式的基礎之上更進一層。第二范式需要確保數據庫表中的每一 列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。 也就是說在一個數據庫表中,一個表中只能保存一種數據,

不可以把多種數據 保存在同一張數據庫表中。

比如要設計一個訂單信息表,因為訂單中可能會有多種商品,所以要將訂單編 號和商品編號作為數據庫表的聯合主鍵。

第三范式(確保每列都和主鍵列直接相關,而不是間接相關)

第三范式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。

比如在設計一個訂單數據表的時候,可以將客戶編號作為一個外鍵和訂單表建立 相應的關系。而不可以在訂單表中添加關於客戶其它信息(比如姓名、所屬公司 等)的字段。

總結:1NF:無重復的列,屬性不可以拆分(強調列的原子性,比如家庭電話和個人電話需要拆開)

   2NF:屬性完全依賴於主鍵

   3NF:屬性不傳遞依賴於其他非主屬性

1.2、范式的優點缺點

優點:避免數據冗余,減少數據的空間,數據變更速度更快

缺點:范式等級越高,表的數量越多,獲取數據時表關聯過多,性能較差

1.3、反范式

范式設計的表無法滿足性能需求時,需要根據業務場景,在范式的基礎上靈活設計

1.業務場景

2.響應時間

3.字段冗余

1.4、反范式和范式的對比

二、基礎規范和命名規范

2.1、基礎規范

想要發揮 MySQL 的最佳性能,需要遵循 3 個基本使用原則。

1.回歸存儲的基本職能(MySQL 數據庫只用於數據的存儲,不進行數據的復雜計算,不承載業務邏輯,確保存儲和計算分離)
2.查詢時盡量單表查詢,減少跨庫查詢和多表關聯
3.杜絕大事務、大SQL、大批量、大字段等性能殺手

大事務:運行步驟較多,涉及的表和字段較多,容易造成資源的爭搶,甚至形成死鎖。一旦事務回滾,會導致資源占用時間過長。

大 SQL:復雜的 SQL 意味着過多的表的關聯,MySQL 數據庫處理關聯超過 3 張表以上的 SQL 時,占用資源多,性能低下。

大批量:意味着多條 SQL 一次性執行完成,必須確保進行充分的測試,並且在業務低峰時段或者非業務時段執行。

大字段:blob、text 等大字段,盡量少用。必須要用時,盡量與主業務表分離,減少對這類字段的檢索和更新。

下面具體講解數據庫的基本設置規則:

  1. 必須指定默認存儲引擎為 InnoDB,並且禁用 MyISAM 存儲引擎,隨着 MySQL 8.0 版本的發布,所有的數據字典表都已經轉換成了 InnoDB,MyISAM 存儲引擎已成為了歷史。
  2. 默認字符集 UTF8mb4,以前版本的 UTF8 是 UTF8mb3,未包含個別特殊字符,新版本的 UTF8mb4 包含所有字符,官方強烈建議使用此字符集。
  3. 關閉區分大小寫功能。設置 lower_case_tables_name=1,即可關閉區分大小寫功能,即大寫字母 T 和小寫字母 t 一樣。
  4. 開啟 per-table 表空間,開啟后,每張業務表會單獨創建一個獨立於系統表空間的表空間,便於空間的回收,數據的遷移。

這里在實踐中有個小問題,如何讓系統中區分大小寫的庫表轉換為不區分大小寫的庫表呢?因為要修改底層數據,還是比較麻煩的,操作步驟如下:

MySQL dump 導出數據庫。

修改參數 lower_case_tables_name=1。

導入備份數據時,必須停止數據庫,停止業務,影響非常大。

禁用功能

MySQL 數據庫提供的功能很全面,但並不是所有的功能性能都高效。

存儲過程、觸發器、視圖、event。為了存儲計算分離,這類功能盡量在程序中實現。這些功能非常不完整,調試、排錯、監控都非常困難,相關數據字典也不完善,存在潛在的風險。一般在生產數據庫中,禁止使用。

lob、text、enum、set。這些字段類型,在 MySQL 數據庫的檢索性能不高,很難使用索引進行優化。如果必須使用這些功能,一般采取特殊的結構設計,或者與程序結合使用其他的字段類型替代。比如:set 可以使用整型(0,1,2,3)、注釋功能和程序的檢查功能集合替代。

2.2、命名規范

  • 名稱的字符范圍為:a-z,0-9和_(下划線)
  • 所有表名小寫
  • 不允許使用-(橫杠)、空格
  • 不允許其他字符作為名稱例如:@&*%¥#等等

庫名:1位數據庫類型代碼+項目簡稱+識別代碼+序號

 

 表名:

字段名:

 三、Innodb表要求

  • 主鍵列,UNSIGNED證書,使用auto_increment(這個如果在實際項目中不一定的,大多數不會用自增,因為在分庫分表會有問題,會用雪花算法計算id)
  • 必須添加comment注解(主要是為了方便他人理解)
  • 必須顯式指定engine(引擎)
  • 表必備三字段:id,xxx_create,xxx_modified(主鍵id,創建時間,更新時間)

四、字段設計要求

數據值進行參考

  • 合理的類型,最短的長度,NotNULL
  • 表字段少而精
  • 單表個數必須控制在2000個以內
  • 單表分表個數必須控制在1024個以內
  • 單表字段數上限控制在20-50

總結

  1. 以高性能為目標,庫表設計以范式為主,根據特殊業務場景使用反范式,允許必要的空間換時間。
  2. 規范數據庫的使用原則,統一規范命名,減少性能隱患,減少隱式轉換。
  3. 高性能表設計的原則:合適的字段、合適的長度、NOT NULL。
  4. 從不同角度思考 IP、timestamp 的轉換,拓寬設計思路。
  5. 規范的命名可提高可讀性,反范式設計可提高查詢性能。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM