tips:如果本文對你有用,請愛心點個贊,提高排名,讓這篇文章幫助更多的人。謝謝大家!比心❤~
如果解決不了,可以在文末加我微信,進羣交流。
設計規範,在分工協作的工作場景中尤其重要,否則團隊之間互相牽制太多,問題多多。
規範設計我想提到如下的幾個規範,其實只是屬於開發規範的一部分內容,可以作爲參考。
規範的本質不是解決問題,而是有效杜絕一些潛在問題,對於千萬級大表要遵守的規範,我梳理了如下的一些細則,基本可以涵蓋我們常見的一些設計和使用問題,比如表的字段設計不管三七二十一,都是varchar(500),其實是很不規範的一種實現方式,我們來展開說一下這幾個規範。
1.配置規範
- MySQL數據庫默認使用InnoDB存儲引擎。
- 保證字符集設置統一,MySQL數據庫相關係統、數據庫、表的字符集使都用UTF8,應用程序連接、展示等可以設置字符集的地方也都統一設置爲UTF8字符集。
注:UTF8格式是存儲不了表情類數據,需要使用UTF8MB4,可在MySQL字符集裏面設置。在8.0中已經默認爲UTF8MB4,可以根據公司的業務情況進行統一或者定製化設置。 - MySQL數據庫的事務隔離級別默認爲RR(Repeatable-Read),建議初始化時統一設置爲RC(Read-Committed),對於OLTP業務更適合。
- 數據庫中的表要合理規劃,控制單表數據量,對於MySQL數據庫來說,建議單表記錄數控制在2000W以內。
- MySQL實例下,數據庫、表數量儘可能少;數據庫一般不超過50個,每個數據庫下,數據表數量一般不超過500個(包括分區表)。
建表規範
-
InnoDB禁止使用外鍵約束,可以通過程序層面保證。
主鍵、外鍵和索引的區別主鍵 外鍵 索引 定義 唯一標識一條記錄,不能有重複的,不允許爲NULL 表的外鍵是另一表的主鍵, 外鍵可以有重複的, 可以是NULL 沒有重複值,可以爲NULL(會使索引無效) 作用 用來保證數據完整性 用來和其他表建立聯繫用的 提高查詢排序的速度 個數 主鍵只能有一個 一個表可以有多個外鍵 一個表可以有多個惟一索引 -
存儲精確浮點數必須使用DECIMAL替代FLOAT和DOUBLE。
-
整型定義中無需定義顯示寬度,比如:使用INT,而不是INT(4)。
-
不建議使用ENUM類型,可使用TINYINT來代替。
-
儘可能不使用TEXT、BLOB類型,如果必須使用,建議將過大字段或是不常用的描述型較大字段拆分到其他表中;另外,禁止用數據庫存儲圖片或文件。
-
存儲年時使用YEAR(4),不使用YEAR(2)。
-
建議字段定義爲NOT NULL。
-
建議DBA提供SQL審覈工具,建表規範性需要通過審覈工具審覈後。
命名規範
- 庫、表、字段全部採用小寫。
- 庫名、表名、字段名、索引名稱均使用小寫字母,並以“_”分割。
- 庫名、表名、字段名建議不超過12個字符。(庫名、表名、字段名支持最多64個字符,但爲了統一規範、易於辨識以及減少傳輸量,統一不超過12字符)。
- 庫名、表名、字段名見名知意,不需要添加註釋。
對於對象命名規範的一個簡要總結如下表4-1所示,供參考。
命名列表
對象中文名稱 | 對象英文全稱 | Mysql對象簡稱 |
---|---|---|
視圖 | view | view_ |
函數 | function | func_ |
存儲過程 | procedure | proc_ |
觸發器 | trigger | trig_ |
普通索引 | index | idx_ |
惟一索引 | unique index | uniq_ |
主鍵索引 | primary key | pk_ |
索引規範
- 索引建議命名規則:idx_col1_col2[_colN]、uniq_col1_col2[_colN](如果字段過長建議採用縮寫)。
- 索引中的字段數建議不超過5個。
- 單張表的索引個數控制在5個以內。
- InnoDB表一般都建議有主鍵列,尤其在高可用集羣方案中是作爲必須項的。
- 建立複合索引時,優先將選擇性高的字段放在前面。
- UPDATE、DELETE語句需要根據WHERE條件添加索引。
- 不建議使用%前綴模糊查詢,例如LIKE “%weibo”,無法用到索引,會導致全表掃描。
- 合理利用覆蓋索引,例如:
SELECT email,uid FROM user_email WHERE uid=xx,如果uid不是主鍵,可以創建覆蓋索引idx_uid_email(uid,email)來提高查詢效率。 - 避免在索引字段上使用函數,否則會導致查詢時索引失效。
- 確認索引是否需要變更時要聯繫DBA。
應用規範
- 避免使用存儲過程、觸發器、自定義函數等,容易將業務邏輯和DB耦合在一起,後期做分佈式方案時會成爲瓶頸。
- 考慮使用UNION ALL,減少使用UNION,因爲UNION ALL不去重,而少了排序操作,速度相對比UNION要快,如果沒有去重的需求,優先使用UNION ALL。
- 考慮使用limit N,少用limit M,N,特別是大表或M比較大的時候。
- 減少或避免排序,如:group by語句中如果不需要排序,可以增加order by null。
- 統計表中記錄數時使用COUNT(),而不是COUNT(primary_key)和COUNT(1);InnoDB表避免使用COUNT()操作,計數統計實時要求較強可以使用Memcache或者Redis,非實時統計可以使用單獨統計表,定時更新。
- 做字段變更操作(modify column/change column)的時候必須加上原有的註釋屬性,否則修改後,註釋會丟失。
- 使用prepared statement可以提高性能並且避免SQL注入。
- SQL語句中IN包含的值不應過多。
- UPDATE、DELETE語句一定要有明確的WHERE條件。
- WHERE條件中的字段值需要符合該字段的數據類型,避免MySQL進行隱式類型轉化。
- SELECT、INSERT語句必須顯式的指明字段名稱,禁止使用SELECT * 或是INSERT INTO table_name values()。
- INSERT語句使用batch提交(INSERT INTO table_name VALUES(),(),()……),values的個數不應過多。