爲了項目的穩定,代碼的高效,管理的便捷,在開發團隊內部會制定各類各樣的規範sql
這裏分享一份咱們定義的MySQL開發規範,歡迎交流拍磚數據庫
數據庫對象命名規範
數據庫對象
命名規範的對象是指數據庫SCHEMA、表TABLE、索引INDEX、約束CONSTRAINTS等的命名約定數組
數據庫對象命名原則
- 命名使用具備意義的英文詞彙,詞彙中間如下劃線分隔
- 命名只能使用英文字母、數字、下劃線
- 避免用MySQL的保留字如:call、group等
- 全部數據庫對象使用小寫字母
數據庫命名規範
- 數據庫名不能超過30個字符
- 數據庫命名必須爲項目英文名稱或有意義的簡寫
- 數據庫建立時必須添加默認字符集和校對規則子句。默認字符集爲UTF8(已遷移dumbo的使用utf8mb4)
- 命名應使用小寫
表命名規範
- 同一個模塊的表儘量使用相同的前綴,表名稱儘量表達含義
- 多個單詞如下劃線(_)分隔
- 表名不能超過30個字符
- 普通表名以t_開頭,表示爲table,命名規則爲t_模塊名(或有意義的簡寫)_+table_name
- 臨時表(運營、開發或數據庫人員臨時用做臨時進行數據採集用的中間表)命名規則:加上tmp前綴和8位時間後綴(tmp_test_user_20181109)
- 備份表(DBA備份用做保存歷史數據的中間表)命名規則:加上bak前綴和8位時間後綴(bak_test_user_20181109)
- 命名應使用小寫
字段命名規範
- 字段命名須要表示其實際含義的英文單詞或簡寫,單詞之間用下劃線(_)進行鏈接
- 各表之間相贊成義的字段必須同名
- 字段名不能超過30個字符
用戶命名規範
- 生產使用的用戶命名格式爲 code_應用
- 只讀用戶命名規則爲 read_應用
數據庫對象設計規範
存儲引擎的選擇
如無特殊需求,必須使用innodb存儲引擎架構
字符集的選擇
如無特殊要求,必須使用utf8或utf8mb4運維
表設計規範
- 不一樣應用間所對應的數據庫表之間的關聯應儘量減小,不容許使用外鍵對錶之間進行關聯,確保組件對應的表之間的獨立性,爲系統或表結構的重構提供可能性
- 表設計的角度不該該針對整個系統進行數據庫設計,而應該根據系統架構中組件劃分,針對每一個組件所處理的業務進行數據庫設計
- 表必需要有PK
- 一個字段只表示一個含義
- 表不該該有重複列
- 禁止使用複雜數據類型(數組,自定義等)
- 須要join的字段(鏈接鍵),數據類型必須保持絕對一致,避免隱式轉換
- 設計應至少知足第三範式,儘可能減小數據冗餘。一些特殊場景容許反範式化設計,但在項目評審時須要對冗餘字段的設計給出解釋
- TEXT字段必須放在獨立的表中,用PK與主表關聯。如無特殊須要,禁止使用TEXT、BLOB字段
- 須要按期刪除(或者轉移)過時數據的表,經過分表解決
- 單表字段數不要太多,建議最多不要大於50個
- MySQL在處理大表時,性能就開始明顯下降,因此建議單表物理大小限制在16GB,表中數據控制在2000W內
- 若是數據量或數據增加在前期規劃時就較大,那麼在設計評審時就應加入分表策略
- 無特殊需求,嚴禁使用分區表
字段設計規範
- INT:如無特殊須要,存放整型數字使用UNSIGNED INT型。整型字段後的數字表明顯示長度
- DATETIME:全部須要精確到時間(時分秒)的字段均使用DATETIME,不要使用TIMESTAMP類型
- VARCHAR:全部動態長度字符串 所有使用VARCHAR類型,相似於狀態等有限類別的字段,也使用能夠比較明顯表示出實際意義的字符串,而不該該使用INT之類的數字來代替;VARCHAR(N),N表示的是字符數而不是字節數。好比VARCHAR(255),能夠最大可存儲255個字符(字符包括英文字母,漢字,特殊字符等)。但N應儘量小,由於MySQL一個表中全部的VARCHAR字段最大長度是65535個字節,且存儲字符個數由所選字符集決定。如UTF8存儲一個字符最大要3個字節,那麼varchar在存放佔用3個字節長度的字符時不該超過21845個字符。同時,在進行排序和建立臨時表一類的內存操做時,會使用N的長度申請內存。(如無特殊須要,原則上單個varchar型字段不容許超過255個字符)
- TEXT:僅僅當字符數量可能超過20000個的時候,纔可使用TEXT類型來存放字符類數據,由於全部MySQL數據庫都會使用UTF8字符集。全部使用TEXT類型的字段必須和原表進行分拆,與原表主鍵單獨組成另一個表進行存放。如無特殊須要,嚴禁開發人員使用MEDIUMTEXT、TEXT、LONGTEXT類型
- 對於精確浮點型數據存儲,須要使用DECIMAL,嚴禁使用FLOAT和DOUBLE
- 如無特殊須要,嚴禁開發人員使用BLOB類型
- 如無特殊須要,字段建議使用NOT NULL屬性,可用默認值代替NULL
- 自增字段類型必須是整型且必須爲UNSIGNED,推薦類型爲INT或BIGINT,而且自增字段必須是主鍵或者主鍵的一部分
索引設計規範
- 索引必須建立在索引選擇性選擇性較高的列上,選擇性的計算方式爲:
select count(distinct(col_name))/count(*) from tb_name;
若是結果小於0.2,則不建議在此列上建立索引,不然大機率會拖慢SQL執行
- 組合索引的首字段,必須在where條件中,對於肯定須要組成組合索引的多個字段,建議將選擇性高的字段靠前放
- 禁止使用外鍵
- Text類型字段若是須要建立索引,必須使用前綴索引
- 單張表的索引數量理論上應控制在5個之內。常常有大批量插入、更新操做表,應儘可能少建索引
- ORDER BY,GROUP BY,DISTINCT的字段須要添加在索引的後面,造成覆蓋索引
- 儘可能使用Btree索引,不要使用其它類型索引
約束設計規範
- PK應該是有序而且無心義的,儘可能由開發人員自定義,且儘量短,使用自增序列。
- 表中除PK之外,還存在惟一性約束的,能夠在數據庫中建立以「uidx_」做爲前綴的惟一約束索引。
- PK字段不容許更新。
- 禁止建立外鍵約束,外鍵約束由應用控制。
- 如無特殊須要,全部字段必須添加非空約束,即not null。
- 如無特殊須要,全部字段必須有默認值。
SQL編寫規範
- 儘可能避免使用
select *
,join語句使用select *
可能致使只須要訪問索引便可完成的查詢須要回表取數
- 嚴禁使用
select * from table
而不加任何where條件
- MySQL中的text類型字段存儲的時候不是和由其餘普通字段類型的字段組成的記錄存放在一塊兒,並且讀取效率自己也不如普通字段塊。若是不須要取回text字段,又使用了
select *
,會讓完成相同功能的sql所消耗的io量大不少,並且增長部分的io效率也更低下
- 在取出字段上可使用相關函數,但應儘量避免出現
now()
,rand()
,sysdate()
,current_user()
等不肯定結果的函數,在Where條件中的過濾條件字段上嚴禁使用任何函數,包括數據類型轉換函數
- 全部鏈接的SQL必須使用
Join ... On ...
方式進行鏈接,而不容許直接經過普通的Where條件關聯方式。外鏈接的SQL語句,可使用Left Join On
的Join方式,且全部外鏈接一概寫成Left Join
,而不要使用Right Join
- 分頁查詢語句所有都須要帶有排序條件,除非應用方明確要求不要使用任何排序來隨機展現數據
- WHERE條件中嚴禁在索引列上進行數學運算或函數運算
- 用
in()
/union
替換or,並注意in的個數小於300
- 嚴禁使用%前綴進行模糊前綴查詢:如:
select id,val from table where val like ‘%name’;
可使用%模糊後綴查詢如:select id,val from table where val like ‘name%’
- 嚴禁使用
INSERT ON DUPLICATE KEY UPDATE、REPLACE INTO、INSERT IGNORE
相關文章推薦閱讀:數據庫設計