注:軍規主要適用於那些大企業,有著併發量大、資料量大的網際網路業務。這類業務架構設計的重點往往是吞吐量,效能優先,對資料庫效能影響較大的資料庫特性較少使用。這類場景的架構方向是「解放資料庫cpu,把複雜邏輯計算放到服務層」,服務層具備更好的擴充套件性,容易實現「增機器就擴充效能」,資料庫擅長儲存與索引,勿讓資料庫揹負過重的任務。
必須使用utf8字符集,新庫預設使用utf8mb4字符集。utf8mb4是utf8的超集,emoji表情以及部分不常見漢字在utf8下會表現為亂碼,故需要公升級至utf8mb4。預設使用這個字符集的原因是:「標準,萬國碼,無需轉碼,無亂碼風險」,並不「節省空間」。
資料表、資料字段必須加入中文注釋
禁止使用外來鍵,如果有外來鍵完整性約束,需要應用程式控制:外來鍵會導致表與表之間耦合,update與delete操作都會涉及相關聯的表,十分影響sql 的效能,甚至會造成死鎖。高併發情況下容易造成資料庫效能,大資料高併發業務場景資料庫使用以效能優先
禁止大表使用join查詢,禁止大表使用子查詢
只允許使用內網網域名稱,而不是ip連線資料庫。不只是資料庫,快取(memcache、redis)的連線,服務(service)的連線都必須使用內網網域名稱,機器遷移/平滑公升級/運維管理…太多太多的好處,如果朋友你還是採用ip直連的,趕緊公升級到內網網域名稱吧。
禁止使用小數儲存貨幣,建議使用整數儲存,小數容易獲取導致錢對不上
禁止使用負向查詢not、!=、<>、!<、!>、not in、not like等,以及%開頭的模糊查詢,會導致全表掃瞄。
一般來說,where過濾條件不會只帶這麼乙個「負向查詢條件」,還會有其他過濾條件,舉個例子:查詢沈劍已完成訂單之外的訂單(好拗口):
select oid from t_order where uid=123 and status != 1;
訂單表5000w資料,但uid=123就會迅速的將資料量過濾到很少的級別(uid建立了索引),此時再接上乙個負向的查詢條件就無所謂了,掃瞄的行數本身就會很少。
但如果要查詢所有已完成訂單之外的訂單:
select oid from t_order where status != 1;
這就掛了,立馬cpu100%,status索引會失效,負向查詢導致全表掃瞄。
禁止使用應用程式配置檔案內的帳號手工訪問線上資料庫
禁止非dba對線上資料庫進行寫操作,修改線上資料需要提交工單,由dba執行,提交的sql語句必須經過測試
分配非dba以唯讀帳號,必須通過vpn+跳板機訪問授權的從庫
開發、測試、線上環境隔離
必須使用innodb儲存引擎:支援事務、行級鎖、併發效能更好、cpu及記憶體快取頁優化使得資源利用率更高
禁止儲存大檔案或者大**:為何要讓資料庫做它不擅長的事情?大檔案和**儲存在檔案系統,資料庫裡存uri多好
線上環境、開發環境、測試環境資料庫內網網域名稱遵循命名規範(自己的命名規範)
庫名、表名、欄位名:小寫,下劃線風格,不超過32個字元,必須見名知意,禁止拼音英文混用
表名t_***,非唯一索引名idx_***,唯一索引名uniq_***
單例項表數目必須小於500
單表列數目必須小於30(這個數目看業務,不過一般不會太多)
表必須有主鍵,例如自增主鍵
必須把字段定義為not null並且提供預設值
禁止使用text、blob型別
必須使用varchar(20)儲存手機號
禁止使用enum,可使用tinyint代替:增加新的enum值要做ddl操作;enum的內部實際儲存就是整數,你以為自己定義的是字串?
單錶索引建議控制在5個以內
單索引欄位數不允許超過5個
禁止在更新十分頻繁、區分度不高的屬性上建立索引
建立組合索引,必須把區分度高的字段放在前面:能夠更加有效的過濾資料
禁止使用select *,只獲取必要的字段,需要顯示說明列屬性
禁止使用insert into t_*** values(***),必須顯示指定插入的列屬性:容易在增加或者刪除欄位後出現程式bug
禁止使用屬性隱式轉換:select uid from t_user where phone=13812345678 會導致全表掃瞄,而不能命中phone索引
禁止在where條件的屬性上使用函式或者表示式
應用程式必須捕獲sql異常,並有相應處理
禁止使用or條件,必須改為in查詢,in的個數建議控制在200以內:舊版本mysql的or查詢是不能命中索引的,即使能命中索引,為何要讓資料庫耗費更多的cpu幫助實施查詢優化呢?
不在資料庫做運算:cpu計算務必移至業務層
控制單錶資料量:單錶記錄控制在1000w
平衡正規化與冗餘:為提高效率犧牲正規化設計,冗餘資料
拒絕3b:拒絕大sql,大事物,大批量
字元轉化為數字
sql語句盡可能簡單:一條sql只能在乙個cpu運算;大語句拆小語句,減少鎖時間;一條大sql可以堵死整個庫
簡單的事務:事務時間盡可能短
limit高效分頁:limit越大,效率越低
少用連線join
使用load data導資料:load data比insert快約20倍;
打散批量更新
Oracle基礎 4 sql執行錯誤時的控制方式
多條sql執行時如果在中間的語句出現錯誤,後續會不會直接執行,如何進行設定,以及其他資料庫諸如mysql是如何對應的,這篇文章將會進行簡單的整理和說明。使用oracle的精簡版建立docker方式的demo環境,詳細可參看 sqlplus system liumiao123 xe select fr...
冬令營線上直播學習筆記4 SQL注入報錯注入
1.什麼是報錯注入?在mysql中使用一些指定的函式來製造報錯,後台沒有遮蔽資料庫的報錯資訊,在語法輸入錯誤的時候將資訊輸出前端顯示,我們可以從報錯資訊中獲取資訊。2.報錯注入常用的函式 updatexml xml文件資料進行查詢和修改的xpath函式 extractvalue xml文件資料進行查...
Java程式設計師面試陷阱大全 4
實踐題 1.abstract class name 這有何錯誤?答案 錯。abstract method必須以分號結尾,且不帶花括號。2.public class something 有錯嗎?答案 錯。區域性變數前不能放置任何訪問修飾符 private,public,和protected final...