我們在項目一開始的設計中,就要忙着考慮數據庫的設計,表、字段、索引、sql等等,而在項目比較大型的時候,團隊開發中由於多人同時進行,那么盡早的進行設計規范是項目開發非常關鍵的一步,那么關於數據庫設計規范有哪些呢,包括以下6項:
1.數據庫命名規范
2.數據庫基本設計規范
3.數據庫索引設計規范
4.數據庫字段設計規范
5.SQL開發規范
6.數據庫操作行為規范
接下來逐一詳細介紹一下各個規范:
1.數據庫命名規范:
1)所有數據庫對象名稱必須使用小寫字母並用下划線分割(MySQL對大小寫是敏感的)
2)禁止使用MySQL的保留關鍵字(比如:select user,from,age from tb_user 這時候識別不出from關鍵字,除非使用`from`,反向單引號來區別)
3)數據庫對象的命名最后能夠見名識義,並且最好不要超過32個字符 ,例如:用戶數據庫 bd_userdb (百度_用戶數據庫) ,用戶賬號表 user_account
4)臨時庫表必須以tmp前綴並以日期為后綴,tmp_user_20180505 提供更加明確的表名
備份庫,備份表必須以bak前綴並以日期為后綴,bak_userdb_20180504 bak_user_20180505
5)所有存儲相同數據的列名和類型必須一致,例如:不同庫表中的user_id(int unsigned not null),那么名稱和類型必須是一致的,否則會產生查詢效率降低等各種問題
2.數據庫基本設計規范:
1)所有表必須使用InnoDB存儲引擎。在MySQL5.6以后,innodb已經成為了默認存儲引擎,它支持事務、行級鎖,更好的恢復性,高並發下性能更好
2)數據庫和表的字符集統一使用UTF-8。為了避免亂碼、性能等問題
3)所有的表和字段都需要添加注釋。使用comment添加備注信息,從一開始就進行數據庫字典的維護
4)盡量控制單表數據量的大小,建議控制在500萬行以內。使用歷史數據歸檔、分庫分表操作手段來控制數據量的大小
5)謹慎使用MySQL中的分區表。跨分區查詢效率比較低,建議采用物理分表的方式來管理大數據
6)盡量做到冷數據分離,減小表寬度。字段太多的情況,盡量分表,將常用的放在一塊,不常用的字段分到其他表中,有效減少磁盤的IO,保證熱數據的緩存命中率
7)禁止在表中建立預留字段。由於無法預知預留字段的類型,后期對改字段進行修改會耗費很多資源,對表進行鎖定等問題
8)禁止存儲圖片、文件等二進制文件,造成MySQL的性能影響。這些應該存儲到專門的圖片、文件服務器中,數據庫中只存儲對應的信息標識。
禁止在線上做數據庫壓力測試
禁止從開發環境、測試環境直連生成環境數據庫
3.索引設計規范:
1)限制每張表索引的數量,建議單表索引不超過5個 。索引並不是越多越好,能提高查詢效率,也能降低效率。應該根據實際情況來建立索引。
2)每個InnoDB表中必須有一個主鍵(唯一非空列)。不用使用頻繁更新的列為主鍵,不使用MD5,UUID,HASH,字符串列作為主鍵。主鍵建議選擇使用自增ID值
3)常見索引列建議:where從句中的列 order by、group by、distinct 中的字段,多表join的關聯列,如果在字句中是單個列,那就單獨索引,有多個列,那可以建立聯合索引
4)如何選擇索引列的順序,區分度最高(比如主鍵列)的列,字段長度小,使用頻繁的列放在聯合索引的最左側
5)避免建立冗余和重復的索引:index(a,b,c),index(a,b),index(a) 對於a就是重復索引
6)對於頻繁的查詢優先考慮使用覆蓋索引:包含了所有查詢字段的索引
7)盡量避免使用外鍵約束。外鍵會影響父表與子表的寫操作從而降低性能
4.數據庫字段設計規范:
1)優先選擇符合存儲需要的最小數據類型。例如:將字符串轉化為數字存儲
對於非負數優先選用無符號型來存儲。例如:主鍵id,無符號比有符號多出一倍的存儲空間。
有符號:signed int -2147483648 ~ 2147483647
無符號:unsigned int 0 ~ 4294967295
varchar(N) N代表的是字符數,而不是字節數,使用UTF8存儲漢字varchar(255)=765個字節
過大的長度會消耗更多的內存,根據字段長度來分配內存。
2)避免使用Text、Blob數據類型,若需要使用,盡量分配到專門的擴展表中
3)避免使用Enum枚舉類型。order by操作效率低。禁止使用數值作為ENum枚舉值
4)盡可能把所有列定義為NOT NULL。索引NULL列需要更多的存儲空間來保存。索引會失效。
5)避免使用字符串來存儲日期時間,使用TIMESTAMP或DATATIME來存儲時間
6)與財務相關的金額類型數據,必須使用Decimal類型。保證數據精度,計算時不丟失精度。
5.數據庫SQL開發規范:
1)建議使用預編譯語句進行數據庫操作。只傳參數,比傳遞sql更加高效,相同語句一次解析之后,多次使用,節約sql解析的成本,提高處理效率。
2)避免數據類型的隱式轉換。隱式轉換導致索引失效,一般在where字句條件中出現的類型轉換,導致了索引失效。
3)合理利用已存在索引,而不是盲目添加索引。
避免使用雙%的查詢條件:like '%123%',只要出現前綴%,索引失效。
一個SQL只能利用到復合索引的一列進行范圍查詢,若聯合索引 index(a,b,c) 對a進行范圍查詢,那么b和c將失效,應當將a放到最右側
使用left join 或 not exists 來優化 not in 操作,not in會使索引失效
4)程序連接不同數據庫時應該使用不同的賬號,禁止跨庫查詢
5)禁止使用 select * 必須使用 select <字段列表> 查詢,消耗過多的IO和cpu以及網絡帶寬資源
6)禁止使用不含字段的insert 語句,為了減少表結構的變更帶來的影響:insert into table values('a','b','c'); 應當指明要插入的列,insert into table(c1,c2,c3) values('a','b','c');
7)避免使用子查詢,可以將子查詢優化為join操作:子查詢都會創建臨時表,占用cpu和io資源,子查詢結果集無法使用索引。
8)避免使用join關聯太多的表:
每關聯一張表,多占用一部分內存(join_buffer_size)
會產生臨時表操作,影響查詢效率
MySQL最多允許關聯61張表,建議不超過5張表
9)減少同數據庫的交互次數
10)使用in代替or。in的值不超過500個,in可以有效使用索引,or不行。
11)禁止使用order by rand() 進行隨機排序,這個操作對性能有很大影響,盡量通過程序來得到隨機值再從數據庫中獲取數據。
12)禁止在where從句中對列進行函數轉換和計算,造成索引的失效。where data(createtime) = '2018-01-01' ,盡量在程序中進行計算
13)在明顯不會出現重復值的時候使用union all 而不是union。union會先加載所有數據到臨時表中然后去重,而union all不會去重。
14)拆分復雜的大SQL成多個小SQL。並行執行小SQL來提高處理效率
6.數據庫操作行為規范:
1)超過100萬行的批量寫操作,要分批多次進行操作:
大批量操作可能造成嚴重的主從延遲問題
binlog日志為row格式時,胡產生大量的日志,造成資源不足
避免產生大事務的操作
2)對於大表使用pt-online-schema-change工具來修改表結構。過程是:先創建新表,然后復制舊表數據到新表,將新表名稱改成舊表名稱,最后刪除舊表
3)禁止為程序使用的賬號賦予super超管權限
4)對於程序連接數據庫賬號,遵循權限最小的原則。程序使用數據庫支行和只能在一個DB下使用,不准跨庫,程序使用的賬號原則上不准有drop權限
以上就是MySQL的一些設計規范,當然不是說一定要遵循以上的原則,具體視實際應用場景而定,通過DBA指導來指定原則。
本文原創,轉載請標注出處:http://www.cnblogs.com/Luke-Me/p/8994432.html
