MySQL數據庫開發規範知識點

前言:數據庫

設計規範更多的是爲了確保數據庫設計的合理性、爲了項目最終的協調穩定性,而命名規範則更多的是爲了確保設計的正式和統一。後端

約定優先於配置(Convention Over Configuration)。緩存

咱們但願團隊中全部人看到設計成果,一眼就能夠明白這個字段是作什麼的、表明的含義是什麼,能夠但不止於見名知意。再者,當前的開發模式,先後端代碼及數據庫文檔、程序文檔、接口文檔等等大都是由工具生成,而其最底層的依據就是數據庫,表、字段的命名註釋同時會影響到工具生成的文檔、代碼中的類屬性方法甚至是前臺頁面的命名註釋,數據庫設計命名的規範關係到整個項目的規範。


表名,字段名等是否區分大小寫:

咱們在基本規範中建議,MySQL數據庫、表、字段等名稱統一使用小寫,單詞間用_下劃線分隔。同時,咱們建議在MySQL數據庫中將Character Set設置爲utf八、將Collation設置爲utf8_bin,並在數據庫配置文件中設置lower_case_table_names=1,固然,Windows系統中默認就是此種設置,無需再作更改。安全

咱們建議在SQLServer中將排序規則設置爲Chinese_PRC_CS_AS,其默認爲Chinese_PRC_CI_AS,由於SQLServer數據庫不用考慮部署在不一樣系統的問題,因此不建議更改除此外的其它編碼、字符序相關的默認設置。咱們上面也說過SQLServer雖然在執行SQL查詢時不區分表名、列名大小寫,但在命名及在可視化管理工具中顯示時卻又區分大小寫,爲了查看方便因此咱們在「基本規範」中要求SQLServer用Pascal的命名方式。數據結構



數據庫功能塊描述:

視圖加前綴是爲了在執行查詢時和表區分開,而存儲過程、函數、約束等,咱們一眼便可看出它是什麼,更況且在可視化管理工具中,這些功能塊原本就是各自獨立展現的。因此本規範中不強制要求在這些功能上加前綴,但若是要統一加的話,建議使用上圖表格中的英文縮寫。併發

 
 
通用字段建議,僅參考:

 

 
 
 
 

數據庫開發規範知識點

目錄:數據庫設計

  • 命名規範
  • 基本設計規範
  • 索引設計規範
  • 字段設計規範
  • SQL開發規範
  • 操做行爲規範

 

命名規範

  • 對象名稱使用小寫字母並用下劃線分割
  • 禁止使用MySQL保留關鍵字
  • 見名識義,最好不超過32個字符。例如:用戶數據庫,mc_userdb(公司+user+db),用戶表,user_account
  • 臨時表,以tmp爲前綴,以日期爲後綴
  • 備份表,以bak爲前綴,以日期爲後綴
  • 存儲相同數據的列名和列類型必須一致(關聯列類型相同用索引高效)函數


     
     

基本設計規範

  • 全部表用Innodb存儲引擎
    • 支持事務
    • 行級鎖
    • 更好的恢復性
    • 高併發的性能更好
  • 數據庫和表的字符集統一使用UTF-8,統一可避免亂碼
  • 全部表和字段添加註釋(COMMENT從句)
  • 儘可能控制單表數據量,建議控制在500萬之內。(不是MySQL的限制,是經驗值)
    • 處理方式:歷史數據歸檔、分庫分表
  • 謹慎使用MySQL分區表
    • 分區表:在物理上表現爲多個文件,在邏輯上表現爲一個表
    • 問題:謹慎選擇分區鍵,跨分區查詢效率可能更低
    • 建議:採用物理分表的方式管理大數據
  • 儘可能作到冷熱數據分離,減少表的寬度
    • 限制:一個表最多4096列
    • 減小磁盤IO,保證熱數據的內存緩存命中率
    • 利用更有效的緩存,避免讀入無用的冷數據
    • 建議:常常一塊兒用的列放在一個表中
  • 禁止在表中建預留字段
    • 沒法見名識義
    • 沒法肯定數據類型
    • MySQL修改預留字段比增長還麻煩,涉及對錶的鎖定
  • 禁止在數據庫中存儲圖片,文件等二進制數據
  • 禁止在線上作數據庫壓力測試
  • 禁止從開發或測試環境直接鏈接生產環境數據庫

 

索引設計規範

  • 限制每張表的索引數量,建議單表索引不超過5個
    • 索引增長查詢效率,可是下降插入和更新效率
    • 禁止給每一列都創建單獨的索引
  • 每一個Innodb表必須有一個主鍵
    • 不使用更新頻繁的列做爲主鍵,不使用多列主鍵,由於更新後就涉及對索引順序的修改,頻繁更新會致使頻繁調整,致使下降性能
    • 不使用UUID,md5,hash字符串做爲主鍵,由於這類哈希不保證插入時遞增的特性
    • 建議:使用自增ID值
  • 在哪創建索引?
    • SELECT, UPDATE, DELETE語句中的WHERE從句中的常出現的列
    • ORDER BY, GROUP BY, DISTINCT中的字段
    • 多表JOIN的關聯列
  • 創建索引的順序?
    • 區分度最高的列放在聯合索引的最左側。區分度計算:Selectivity = Distinct Values / Total Number Rows,區分度最大的就是主鍵(區分度爲1)
      • 區分度差很少的狀況下,儘可能把字段長度小的列放在聯合索引的最左邊
        • 二者還差很少的狀況下,使用最頻繁的列放在聯合索引的左側
  • 避免創建冗餘索引和重複索引
    • 重複索引例子:primary key(id), index(id), unique index(id)這三個就重複創建id的索引了
    • 冗餘索引例子:index(a,b,c), index(a,b), index(a)對於a來講就重複創建了。
  • 對於頻繁的查詢優先考慮使用覆蓋索引。
    • 覆蓋索引:包含了全部查詢字段的索引
    • 避免Innodb表進行索引的二次查找
    • 能夠把隨機IO變爲順序IO加快查詢效率
  • 儘可能避免使用外鍵
    • 外鍵是用於保證數據的參照完整性,但建議在業務端實現。
    • MySQL外鍵會創建索引
    • 不建議使用外鍵約束
    • 表與表之間的關聯鍵創建索引是必須的
    • 外鍵會影響父表和子表的寫操做而下降性能(檢查約束致使的)

字段設計規範

  • 優先選擇符合存儲須要的最小的數據類型
    • 將字符串轉化爲數字類型存儲
    • 非負的用無符號整形
    • VARCHAR(N)的N表明是字符數,不是字節數,使用UTF-8存儲漢字VARCHAR(255)=765個字節
    • 過大的長度會消耗更多的內存
  • 避免使用TEXTBLOB數據類型
  • 避免使用ENUM數據類型
    • 修改ENUM值會致使表結構的修改
    • ENUMORDER BY須要額外操做,效率低
    • 禁止使用數值做爲ENUM的枚舉值
  • 儘量把全部列定義爲NOT NULL
    • 索引NULL列須要額外空間,佔用更多空間
  • 使用TIMESTAMPDATETIME類型存儲時間。不要用字符串存儲日期類型(沒法利用內置日期函數並且佔用更多空間)
  • 涉及財務的金額,必須用DECIMAL類型
    • 精確浮點,計算不會丟失精度
    • 佔用空間由定義的寬度決定
    • 可用於存儲比BIGINT更大的整數數據

SQL開發規範

  • 建議使用預編譯語句進行數據庫操做
    • 只傳參數,屢次使用,執行更快
    • 可避免動態SQL注入問題
  • 避免數據類型的隱式轉換
    • 會致使索引失效
  • 合理利用存在索引,而不是盲目增長索引
  • 充分利用表上已經存在的索引
    • 避免使用雙%號的查詢條件,如a LIKE '%123%'
    • 一個SQL只能利用到複合索引中的一列進行範圍查詢
    • 使用LEFT JOINNOT EXISTS 來優NOT IN操做(可能致使索引失效)
  • 禁止跨庫查詢,程序鏈接不一樣的數據庫使用不一樣的帳號
    • 爲數據庫遷移和分庫分表留出餘地
    • 下降業務耦合度
    • 避免安全風險
  • 禁止使用SELECT *,須要用SELECT <字段列表>查詢
    • *返回不須要的字段
    • 沒法使用覆蓋索引
  • 禁止使用不含字段列表的INSERT語句
    • 禁止這種INSERT INTO t VALUES('a','b','c')應該帶上INSERT INTO t(c1,c2,c3) VALUES('a','b','c')
  • 避免使用子查詢,能夠把子查詢優化爲JOIN操做
    • 子查詢的結果集沒法使用索引
    • 子查詢會產生臨時表操做,若是子查詢數據量大則嚴重影響效率
  • 避免使用JOIN關聯太多的表
    • JOIN一個表會多佔用一部份內存(join_buffer_size)
    • 會產生臨時表,影響查詢效率
    • MySQL最多容許關聯61個表,建議不超過5個
  • 減小同數據庫的交互次數
    • 數據庫更適合處理批量操做
    • 合併多個操做,能夠提升處理效率
  • 使用IN代替OR
    • IN的值不超過500個
    • IN的操做能夠有效的利用索引
  • 禁止使用ORDER BY rand()進行隨機排序
    • 會加載到內存再排序,消耗大量CPU和IO和內存
    • 建議:在程序中生成隨機值,再獲取數據
  • 禁止WHERE從句中隊列進行函數轉換和計算
    • 致使沒法使用索引
  • 明顯不會有重複值的用UNION ALL而不是UNION
    • UNION會把全部數據放到臨時表中後再進行去重操做
    • UNION ALL則不會作去重操做
  • 拆分複雜的大SQL爲多個小SQL
    • 一個SQL只用一個CPU計算
    • 拆分後能夠並行執行

操做行爲規範

  • 超過100萬行的批量寫操做,要分批屢次進行操做
    • 注意以前提到的儘可能合併操做是針對查詢
    • 大批量的可能會形成主從延遲
    • binlog日誌爲row格式時會產生大量的日誌
    • 避免產生大事務操做,形成鎖定和大堵塞。
  • 對大表數據結構的修改必定要謹慎,會形成嚴重的鎖表操做。尤爲是生產環境,是不能忍受的。
  • 對於大表使用pt-online-schema-change(PERCONA公司的工具)修改表結構
    • 複製出一個新表,再修改新表爲原表名稱
    • 避免主從延遲
    • 避免修改時的鎖表
  • 禁止程序使用super權限的帳號
    • super能夠在達到最大鏈接限制連上用戶,可是隻能有一個super帳號鏈接,應該交給DBA處理問題用,不該被程序佔用
  • 數據庫帳號遵循權限最小原則
    • 只須要查詢就別給其餘操做權限
    • 數據庫帳號只能在同一個DB下使用,不容許跨庫
    • 程序的帳號原則上不容許有drop權限
歡迎fork :一隻阿木木
相關文章
相關標籤/搜索