1.引子
對於後端開發工程師來講,數據庫設計,優化是一項必備的技能,瞧瞧咱們是否是常常在項目中吐槽其餘小夥伴編寫的sql語句,既如此,千萬不要讓其餘小夥伴有機會吐槽回來。甚至咱們應該作到在編寫sql語句的時候,腦海中已經浮現了該sql語句的執行軌跡,這樣一來,相信咱們寫出的sql語句質量會很是高。mysql
由於工做上的須要,抽空整理了一版數據庫設計開發參考規範,我把它叫作必知必會之數據庫規約,並分享給你,指望給你帶來一些收穫!sql
我將內容分爲:數據庫
-
建表規範後端
-
sql規範bash
-
索引規範網絡
2.建表規範
2.1.範式化
#1.關係數據庫表設計基礎理論:第一範式、第二範式、第三範式 ##1.1.第一範式 強調列的原子性,字段不可再分割 ##1.2.第二範式 強調行的惟一性,不可存在相同的行(表中必須有主鍵字段) ##1.3.第三範式 強調主外鍵關聯,消除冗餘性(須要注意,在互聯網項目中,通常不創建主外鍵約束,在代碼層面實現業務關聯) 所以今天咱們有時候在強調反範式化設計,就是針對的第三範式
2.2.存儲引擎
#1.mysql數據庫,存儲引擎建議選擇InnoDB ##緣由: InnoDB存儲引擎支持事務、支持行級鎖(併發性能更好)、支持Crash safe能力(redo log能力)
3.3.數據類型
#1.選擇合適的數據類型 ##1.1.整數 TinyInt,SmallInt,MediumInt,Int,BigInt 使用的存儲8,16,24,32,64位存儲空間。使用Unsigned表示不容許負數,可使正數的上線提升一倍 ##1.2.實數 Float,Double , 支持近似的浮點運算 Decimal,用於存儲精確的小數(一般用於貨幣存儲) ##1.3.字符串 VarChar,存儲變長的字符串。須要1或2個額外的字節記錄字符串的長度 Char,定長,適合存儲固定長度的字符串,如MD5值。 Blob,Text 爲了存儲很大的數據而設計的。分別採用二進制和字符的方式 ##1.4.時間 DateTime,保存大範圍的值,佔8個字節,存儲範圍(1001-9999)。 TimeStamp,推薦,與UNIX時間戳相同,佔4個字節,存儲範圍(1970-2038)
如何選擇?併發
-
儘可能使用對應的數據類型。好比不要用字符串類型保存時間oracle
-
選擇更小的數據類型。能用TinyInt,就不用Int框架
-
標識列(identifier column),建議使用整型,不推薦字符串類型,佔用更多空間,並且計算速度比整型慢 數據庫設計
2.4.字符集
#1.統一字符集(客戶端、服務端),建議使用utf-8字符集,mysql數據庫須要注意真正的utf-8字符集應該選擇:utf8mb4
2.5.命名
#1.見名知意,禁止拼音英文混用 #2.約定庫名、表名、字段名小寫、下劃線風格,不超過32個字符 #3.禁止使用保留字
2.6.註釋
#1.表、字段必須添加必要的註釋(千萬不要偷懶)
2.7.默認值
#1.字段定義爲 NOT NULL 且需提供默認值 ##緣由: NULL的列使索引/索引統計/值比較都更加複雜,數據庫自身更難優化 NULL這種類型Msql內部須要進行特殊處理,增長數據庫處理記錄的複雜性;同等條件下,表中有較多空字段的時候,數據庫的處理性能會下降不少 NULL值須要更多的存儲空,不管是表仍是索引中每行中的NULL的列都須要額外的空間來標識
2.8.手寫schema
#1.禁止經過工具,或者orm框架生產schema。所有ddl sql必須手工提供
3.sql規範
3.1.select *
#1.大原則:客戶端須要什麼,就返回什麼 #2.讀取不須要的列,會增長cpu、Io、網絡開銷 #3.select * 不能有效利用覆蓋索引
3.2.where條件
#1.禁止where條件屬性上,執行隱式轉換,隱式轉換會讓索引失效 好比select id, name,phone from table where phone=18688438888 (phone是字符串類型) #2.禁止where條件屬性上,使用函數或者表達式,where條件屬性上使用函數,會讓索引失效,同理表達式讓索引失效 好比select id,name,age where age+1 = 10
3.3.外鍵關聯
#1.禁止使用外鍵、級聯。一切外鍵概念必需要應用層解決 ##緣由: 外鍵與級聯更新適用於單機低併發,不適合分佈式、高併發集羣 外鍵影響數據庫的插入速度 級聯更新是強阻塞,存在數據庫更新風暴的風險
3.4.or鏈接條件
#1.儘可能避免在where子句中,經過or鏈接條件 ##緣由: or 鏈接條件可能會使索引失效 經過union all 替換 or鏈接條件
3.5.模糊查詢
#1.主流關係數據庫oracle、mysql支持前綴索引 #2.模糊查詢應用場景,like子句中要放在後面 好比:select id,name from table where name like '小明%'
3.6.表關聯
#1.表關聯數量,儘可能不要超過5個表,連表越多,編譯的時間和開銷也就越大 #2.把鏈接表拆開成較小的幾個執行,可讀性更高 #3.表之間的關聯,讓小表成爲驅動表 #4.多個表關聯時,每一列上必須明確來源表 好比:select A.id,B.name from A,B WHERE A.id=B.id
3.7.限制結果集
#1.若是明確查詢結果最多隻有1條記錄,請使用好limit=1 或者rownum<=1
4.索引規範
4.1.索引原理
#1.索引的原理:空間換時間 ##優點: 減小查詢掃描的數據量 避免排序和零時表 將隨機IO變爲順序IO ##代價: 須要更多的存儲空間 影響更新維護效率(增刪改)
4.2.索引選擇
#1.B-tree索引 實踐中使用更多的索引類型 支持精確查找、範圍查找、前綴查找、支持排序 #2.hash索引 查詢效率更高,但只支持精確查找 不支持範圍、前綴查找,不支持排序
4.3.索引實踐
#1.索引字段區分度要高(索引字段值不能有太多重複數據) ##1.1.好比:select id,name,age from user where sex=1 ##1.2.解釋: 性別只有男,女,每次過濾掉的數據不多,不宜使用索引 經驗上,能過濾80%數據時就可使用索引。對於訂單狀態,若是狀態值不多,不宜使用索引,若是狀態值不少,可以過濾大量數據,則應該創建索引 #2.用好複合索引 ##2.1.複合索引,指多個字段聯合起來建立索引,好比字段A、字段B,聯合建立索引(A,B) ##2.2.利用複合索引,能夠有效減小索引數量,索引(A,B),至關於創建了索引(A),與索引(A,B) #3.刪除冗餘重複的索引,緣由參考索引的代價