寫在前面:無規矩不成方圓。對於剛加入互聯網的朋友們,確定會接觸到MySQL,MySQL做爲互聯網最流行的關係型數據庫產品,它有它擅長的地方,也有它不足的短板,針對它的特性,結合互聯網大多應用的特色,筆者根據本身多年互聯網公司的MySQL DBA經驗,現總結出互聯網MySQL的一些開發規範,僅供參考。
mysql
做者是微信訂閱號yunweibang特約技術專家劉秋岐,多年數據庫經驗,若有問題能夠訂閱yunweibang並留言。sql
摘要:數據庫
基礎規範微信
命名規範ide
庫、表、字段開發設計規範函數
索引規範工具
SQL規範性能
流程規範測試
一大數據
基礎規範(1) 使用INNODB存儲引擎
(2) 表字符集使用UTF8
(3) 全部表都須要添加註釋
(4) 單表數據量建議控制在5000W之內
(5) 不在數據庫中存儲圖、文件等大數據
(6) 禁止在線上作數據庫壓力測試
(7) 禁從測試、開發環境直連數據庫
二
命名規範(1) 庫名錶名字段名必須有固定的命名長度,12個字符之內
(2) 庫名、表名、字段名禁止超過32個字符。須見名之意
(3) 庫名、表名、字段名禁止使用MySQL保留字
(4) 臨時庫、表名必須以tmp爲前綴,並以日期爲後綴
(5) 備份庫、表必須以bak爲前綴,並以日期爲後綴
三
庫、表、字段開發設計規範(1) 禁使用分區表
(2) 拆分大字段和訪問頻率低的字段,分離冷熱數據
(3) 用HASH進散表,表名後綴使進制數,下標從0開始
(4) 按日期時間分表需符合YYYY[MM][DD][HH]格式
(5) 採用合適的分庫分表策略。例如千庫十表、十庫百表等
(6) 儘量不使用TEXT、BLOB類型
(7) 用DECIMAL代替FLOAT和DOUBLE存儲精確浮點數
(8) 越簡單越好:將字符轉化爲數字、使用TINYINT來代替ENUM類型
(9) 全部字段均定義爲NOT NULL
(10) 使用UNSIGNED存儲非負整數
(11) INT類型固定佔用4字節存儲
(12) 使用timestamp存儲時間
(13) 使用INT UNSIGNED存儲IPV4
(14) 使用VARBINARY存儲大小寫敏感的變長字符串
(15) 禁止在數據庫中存儲明文密碼,把密碼加密後存儲
(16) 用好數值類型字段
Tinyint (1Byte)
smallint (2Byte)
mediumint (3Byte)
int (4Byte)
bigint (8Byte)
類型 |
字節 |
最小值 |
最大值 |
(帶符號的/無符號的) |
(帶符號的/無符號的) |
||
TINYINT |
1 |
-128 |
127 |
無符號 |
0 |
255 |
|
SMALLINT |
2 |
-32768 |
32767 |
無符號 |
0 |
65535 |
|
MEDIUMINT |
3 |
-8388608 |
8388607 |
無符號 |
0 |
16777215 |
|
INT |
4 |
-2147483648 |
2147483647 |
無符號 |
0 |
4294967295 |
|
BIGINT |
8 |
-9223372036854775808 |
9223372036854775807 |
無符號 |
0 |
18446744073709551615 |
若是數值字段沒有那麼大,就不要用 bigint
(17) 存儲ip最好用int存儲而非char(15)
(18) 不容許使用ENUM
(19) 避免使用NULL字段
NULL字段很難查詢優化,NULL字段的索引須要額外空間,NULL字段的複合索引無效
(20) 少用text/blob,varchar的性能會比text高不少,實在避免不了blob,請拆表
(21) 數據庫中不容許存儲大文件,或者照片,能夠將大對象放到磁盤上,數據庫中存儲它的路徑
四
索引規範1、索引的數量要控制:
(1) 單張表中索引數量不超過5個
(2) 單個索引中的字段數不超過5個
(3) 對字符串使用前綴索引,前綴索引長度不超過8個字符
(4) 建議優先考慮前綴索引,必要時可添加僞列並創建索引
2、主鍵準則
(1) 表必須有主鍵
(2) 不使用更新頻繁的列做爲主鍵
(3) 儘可能不選擇字符串列做爲主鍵
(4) 不使用UUID MD5 HASH這些做爲主鍵(數值太離散了)
(5) 默認使非空的惟一鍵做爲主鍵
(6) 建議選擇自增或發號器
3、重要的SQL必須被索引,好比:
(1) UPDATE、DELETE語句的WHERE條件列
(2) ORDER BY、GROUP BY、DISTINCT的字段
4、多表JOIN的字段注意如下:
(1) 區分度最大的字段放在前面
(2) 核SQL優先考慮覆蓋索引
(3) 避免冗餘和重複索引
(4) 索引要綜合評估數據密度和分佈以及考慮查詢和更新比例
5、索引禁忌
(1) 不在低基數列上創建索引,例如「性別」
(2) 不在索引列進行數學運算和函數運算
6、儘可能不使用外鍵
(1) 外鍵用來保護參照完整性,可在業務端實現
(2) 對父表和子表的操做會相互影響,下降可用性
7、索引命名:非惟一索引必須以 idx_字段1_字段2命名,惟一因此必須以uniq_字段1_字段2命名,索引名稱必須所有小寫
8、新建的惟一索引必須不能和主鍵重複
9、索引字段的默認值不能爲NULL,要改成其餘的default或者空。NULL很是影響索引的查詢效率
10、反覆查看與表相關的SQL,符合最左前綴的特色創建索引。多條字段重複的語句,要修改語句條件字段的順序,爲其創建一條聯合索引,減小索引數量
11、能使用惟一索引就要使用惟一索引,提升查詢效率
12、研發要常用explain,若是發現索引選擇性差,必須讓他們學會使用hint
五
SQL規範(1) sql語句儘量簡單
大的sql想辦法拆成小的sql語句(充分利用QUERY CACHE和充分利用多核CPU)
(2) 事務要簡單,整個事務的時間長度不要太長
(3) 避免使用觸發器、函數、存儲過程
(4) 下降業務耦合度,爲sacle out、sharding留有餘地
(5) 避免在數據庫中進數學運算(MySQL不擅長數學運算和邏輯判斷)
(4) 不要用select *,查詢哪幾個字段就select 這幾個字段
(5) sql中使用到OR的改寫爲用 IN() (or的效率沒有in的效率高)
(6) in裏面數字的個數建議控制在1000之內
(7) limit分頁注意效率。Limit越大,效率越低。能夠改寫limit,好比例子改寫:
select id from tlimit 10000, 10; => select id from t where id > 10000 limit10;
(9) 使用union all替代union
(10) 避免使大表的JOIN
(11) 使用group by 分組、自動排序
(12) 對數據的更新要打散後批量更新,不要一次更新太多數據
(13) 減小與數據庫的交互次數
(13) 注意使用性能分析工具
Sql explain / showprofile / mysqlsla
(14) SQL語句要求全部研發,SQL關鍵字所有是大寫,每一個詞只容許有一個空格
(15) SQL語句不能夠出現隱式轉換,好比 select id from 表 where id='1'
(16) IN條件裏面的數據數量要少,我記得應該是500個之內,要學會使用exist代替in,exist在一些場景查詢會比in快
(17) 能不用NOT IN就不用NOTIN,坑太多了。。會把空和NULL給查出來
(18) 在SQL語句中,禁止使用前綴是%的like
(19) 不使用負向查詢,如not in/like
(19) 關於分頁查詢:程序裏建議合理使用分頁來提升效率limit,offset較大要配合子查詢使用
(20) 禁止在數據庫中跑大查詢
(21) 使預編譯語句,只傳參數,比傳遞SQL語句更高效;一次解析,屢次使用;下降SQL注入機率
(22) 禁止使order by rand()
(23) 禁單條SQL語句同時更新多個表
六
流程規範(1) 全部的建表操做須要提早告知該表涉及的查詢sql;
(2) 全部的建表須要肯定創建哪些索引後才能夠建表上線;
(3) 全部的改表結構、加索引操做都須要將涉及到所改表的查詢sql發出來告知DBA等相關人員;
(4) 在建新表加字段以前,要求研發至少要提早3天郵件出來,給dba們評估、優化和審覈的時間
(5)批量導入、導出數據必須提早通知DBA協助觀察
(6) 禁在線上從庫執行後臺管理和統計類查詢
(7) 禁有super權限的應用程序帳號存在
(8) 推廣活動或上線新功能必須提早通知DBA進行流量評估
(9) 不在業務高峯期批量更新、查詢數據庫
做者是微信訂閱號yunweibang特約技術專家劉秋岐,多年數據庫經驗,若有問題能夠訂閱yunweibang並留言。
轉載本文請務必帶有本訂閱號二維碼及做者信息
出自:http://mp.weixin.qq.com/s?plg_nld=1&plg_uin=1&mid=207132223&idx=1&plg_nld=1&scene=22&plg_auth=1&__biz=MzA3MzYwNjQ3NA%3D%3D&plg_dev=1&srcid=11031H8kGQS39BOTBXDbsowL&plg_usr=1&plg_vkey=1&sn=f5d98146f28235d91fe3e675cead4ce5#rd