專業級的MySQL開發設計規範及SQL編寫規範
在團隊開發過程中為了專案的穩定,程式碼的高效,管理的便捷制定內部種開發設計規範是必不可少的,
這裡分享一份我們定義MySQL開發設計規範包括表設計規範,欄位設計規範,SQL編寫規範
資料庫物件命名規範
資料庫物件
命名規範的物件是指資料庫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
本文做個拋磚引玉,每個團隊都有自己的開發設計規範,Mysql開發設計規範不單單隻有這些,希望本文對您有所啟發