必知必會之數據庫規約

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.刪除冗餘重複的索引,緣由參考索引的代價
相關文章
相關標籤/搜索