#一 數據庫設計規范
## 1.數據庫命名規范
>- 所有數據庫對象名稱必須使用小寫字母并用下劃線分割
>>- 因為Linux是嚴格區分大小寫的故Mysql也得大小寫敏感
>- 所有數據庫對象名稱禁止使用mysql保留關鍵字
>- 數據庫對象的命名要能夠做到見名識義,并且最好不要超過32個字符
>- 臨時表必須以tmp為前綴并以日期為后綴
>- 備份庫,別分表必須以bak為前綴并以日期為后綴
>- 所有存儲相同數據的列名和列類型必須一致
## 2.數據庫基本設計規范
>- 所有表必須使用Innodb存儲引擎(5.6以后默認引擎)
>>- 支持事務,行級鎖,更好的恢復性,高并發性能更好
>- 數據庫和表的字符集同意使用UTF8
>- 字符集統一可以避免亂碼
>- mysql中utf8字符集漢字點3個字節,Ascii占用一個字節
>- 所有表和字段都需要添加注釋
>- 使用comment從句添加表和列的備注
>- 從一開始就進行數據字典的維護
>- 盡量控制點數據量的大小,建議控制在500萬以內
>- 可以用歷史數據歸檔,分庫分表等手段來控制數據大小
>- 謹慎使用musql分區表
>- 分區表在物理上表現為多個文件,在邏輯上表現為一個表
>- 謹慎選擇分區鍵,款分區查詢效率可能更低
>- 建議采用物理分表的方式管理大數據
>- 盡量做到冷熱數據分離,減少表的寬度
>- 減少磁盤IO,保證熱數據的內存緩存命中率
>- 利用更有效的利用緩存,避免讀入無用的冷數據
>- 經常一起使用的列放到一個表中
>- 禁止在表中建立預留字段
>- 預留字段的命名很難做到見名識義
>- 預留字段無法確認存儲的數據類型,所以無法選擇合適的類型
>- 對預留字段類型的修改,對表進行鎖定
>- 禁止在數據庫中存儲圖片,文件等二進制數據
>- 禁止在線上做數據庫壓力測試
>- 禁止從開發環境,測試環境直接連接生產環境的數據庫
## 3.數據庫索引設計規范
>- 索引對數據庫的查詢性能來說非常重要的
>- 不要濫用索引
>- 限制每張表上的索引數量,建議單張表索引不超過5個
>- 索引并不是越多越好!索引可以提高效率同樣也可以降低效率
>- 禁止給表中的每一列都建立單獨的索引
>- 每個Innodb表必須有一個主鍵
>- 不能使用頻繁更新的列作為主鍵,不使用多列主鍵
>- 不適用UUID,MD5,HASH,字符串列作為主鍵
>- 主鍵建議選擇使用自增ID
>- 常見索引列建議
>- select,update,delete語句的where從句中的列包含在order by group by distinct中的字段(最好建立聯合索引)
>- 多表join的關聯列建立索引
>- 如何選擇索引列的順序
>- 區分度最高的列放在聯合索引的最左側
>- 盡量把字段長度小的類放在聯合索引的最左側
>- 使用最頻發的列放到聯合索引的左側
>- 避免建立冗余索引和重復索引
>- 如:primary key(id) index(id) unique index(id)
>- 冗余索引:index(a,b,c) index(a,b) index(a)
>- 對于頻繁的查詢優先考慮使用覆蓋索引
>- 避免innodb表進行索引的二次查找
>- 可以把隨機io變成順序io加快查詢效率
>- 盡量避免使用外鍵(約束)
>- 外鍵可用于保證數據的參照完整性,但建議在業務端實現
>- 外鍵會影響父表和字表的寫操作從而降低性能
## 4.數據庫字段設計規范
>- 有限選擇符合存儲需要的最小的數據類型
>>- 將字符床轉換為數字類型存儲 如:INET_ATON('255.255.255.255')=4294967295 INET_NTOA(4294967295) = '255.255.255.255'
>- 有限選擇符合存儲需要的最小的數據類型(多一倍空間)
>- 有限選擇符合存儲需要的最小的數據類型
>>- VARCHAR(N)中的N代表的是字符數,而不是字節數,使用UTF8存儲漢字varchar(255)=765字節,過大的長度會消耗更多的內存
>- 避免使用TEXT,BLOB數據類型
>>- 建議把BLOB或者TEXT列分離到單獨的擴展表中,TEXT或者BLOB類型只能使用前綴索引
>- 避免使用ENUM數據類型,修改ENUM值需要使用ALTER語句,ENUM類型的ORDER BY操作效率低,需要額外操作,禁止使用數值作為ENUM的枚舉值
>- 盡可能把所有列定義為NOT NULL
>>- 索引NULL列需要額外的空間來保存,所以要占用更多的空間進行比較和計算時要對NULL值做特別的處理
>- 不能用字符串存儲日期型數據
>>- 缺點1:無法用日期函數進行計算和比較,缺點2:用字符串存儲日期要占用更多的空間
>- 使用TIMESTAMP或DATETIME類型存儲時間(TIMESTAMP占用4字節和INT相同,但比INT可讀性高)超出了用DATETIME
>- 非精準數據類型float,double,同財務相關的金額類數據,必須使用 **decimal** 類型
Decimal類型為精準浮點數,在計算時不會丟失精度,占用空間由定義的寬度決定
可用于存儲比bigint更大的整數數據,比varchar更高效
## 5.數據庫sql開發規范
>- 建議使用預編譯語句進行數據操作(防止注入)
>>- 只傳參數,比傳遞sql語句更高效,相同語句可以一次解析,多次使用,提高處理效率
>- 避免數據類型的隱式轉換
>- 充分利用表上已經存在的索引,避免使用雙%的查詢條件
>>- 一個sql只能利用到復合索引中的一列進行范圍查詢,使用left join 或者not exists來優化not in操作
>- 程序連接不同的數據庫使用不同的賬號,禁止跨庫查詢
>- 禁止使用select*查詢,消耗很多的cpu和io以及網絡帶寬
無法使用覆蓋索引,可減少表結構變更帶來的影響
>- 禁止使用不含字段列表的insert語句
>- 避免使用子查詢,可以把子查詢優化為join操作
>>- 子查詢的結果集無法使用索引,子查詢會產生臨時表操作,如果子查詢數據量大則嚴重影響效率,消耗過多的cpu及io資源
>- 避免使用join關聯太多的表
>>- 每join一個表多占用一部分內存,會產生臨時表影響查詢效率,mysql最多關聯61個表,建議不要超過5個
>- 減少同數據庫的相互次數
>>- 數據庫更適合處理批量操作,合并多個相同的操作到一起,可以提高處理效率
>- 使用in代替 or
>- 禁止使用order by rand()進行隨機排序操作
>- where從句中禁止對列進行函數轉換和計算
>- 在明顯不會有重復值時使用UNION ALL而不是UNION
>>- UNION會把所有數據放到臨時表中后在進行去重操作,union all不會在對數據集進行合并
>- 拆分復雜的大sql為多個小sql
## 6.數據庫操作行為規范
>- 超過100萬行的批量寫操作,要分批多次進行操作
>- 對于大表使用pt-online-schema-change修改表結構
>- 禁止為程序使用的賬號賦予super權限
>- 對于程序連接數據庫,遵循權限最小原則
>>- 程序使用數據庫賬號只能在一個DB下使用,不準跨庫,程序使用的賬號原則上不準有drop權限