前言:數據庫
設計規範更多的是爲了確保數據庫設計的合理性、爲了項目最終的協調穩定性,而命名規範則更多的是爲了確保設計的正式和統一。後端
約定優先於配置(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開發規範
- 操做行爲規範
命名規範
基本設計規範
- 全部表用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
個字節
- 過大的長度會消耗更多的內存
- 避免使用
TEXT
、BLOB
數據類型
- 避免使用
ENUM
數據類型
- 修改
ENUM
值會致使表結構的修改
-
ENUM
的ORDER BY
須要額外操做,效率低
- 禁止使用數值做爲ENUM的枚舉值
- 儘量把全部列定義爲
NOT NULL
- 使用
TIMESTAMP
或DATETIME
類型存儲時間。不要用字符串存儲日期類型(沒法利用內置日期函數並且佔用更多空間)
- 涉及財務的金額,必須用
DECIMAL
類型
- 精確浮點,計算不會丟失精度
- 佔用空間由定義的寬度決定
- 可用於存儲比
BIGINT
更大的整數數據
SQL開發規範
- 建議使用預編譯語句進行數據庫操做
- 只傳參數,屢次使用,執行更快
- 可避免動態SQL注入問題
- 避免數據類型的隱式轉換
- 合理利用存在索引,而不是盲目增長索引
- 充分利用表上已經存在的索引
- 避免使用雙%號的查詢條件,如
a LIKE '%123%'
- 一個SQL只能利用到複合索引中的一列進行範圍查詢
- 使用
LEFT JOIN
或 NOT 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
操做行爲規範
- 超過100萬行的批量寫操做,要分批屢次進行操做
- 注意以前提到的儘可能合併操做是針對查詢
- 大批量的可能會形成主從延遲
- binlog日誌爲row格式時會產生大量的日誌
- 避免產生大事務操做,形成鎖定和大堵塞。
- 對大表數據結構的修改必定要謹慎,會形成嚴重的鎖表操做。尤爲是生產環境,是不能忍受的。
- 對於大表使用pt-online-schema-change(PERCONA公司的工具)修改表結構
- 複製出一個新表,再修改新表爲原表名稱
- 避免主從延遲
- 避免修改時的鎖表
- 禁止程序使用super權限的帳號
- super能夠在達到最大鏈接限制連上用戶,可是隻能有一個super帳號鏈接,應該交給DBA處理問題用,不該被程序佔用
- 數據庫帳號遵循權限最小原則
- 只須要查詢就別給其餘操做權限
- 數據庫帳號只能在同一個DB下使用,不容許跨庫
- 程序的帳號原則上不容許有drop權限
歡迎fork :一隻阿木木