SQL——数据库使用规范(入门规范)
一.基礎規范
1.使用InnoDB存儲引擎
2.庫、表、列字符集使用utf8mb4,utf8mb4兼容utf8且可以存儲表情字符。
3.建議所有表、所有列都需要添加注釋
4.不在數據庫中存儲圖,文件等大數據,可以將大對象放到磁盤上,數據庫中存儲它的路徑
5.不在線上做數據庫壓力測試 (可在預發布環境)
6.不在線下開發環境直連線上數據庫主庫
二.命名規范
1.庫名.表名.字段名必須使用小寫字母或數字,禁止出現數字開頭,禁止連個下劃線中間只出現數字,使用下劃線“_”分割,分表使用后綴為 “_xx",例如"order_01,order_99"
2.庫名.表名.字段名禁止超過32個字符。須見名知意
3.庫名.表名.字段名禁止使用MySQL保留字
4.臨時庫.表名必須以tmp為前綴,并以日期為后綴
5.備份庫.表必須以bak為前綴,并以日期為后綴
三. 庫.表.字段開發設計規范
1.按日期時間分表需符合YYYY[MM][DD][HH]格式
2.對日志型表選擇分區表策略
3.建議不使用TEXT.BLOB類型
4.建議所有字段均定義為NOT NULL,默認值為空的寫法為NOT NULL DEFAULT ‘’ 而不是 NOT NULL DEFAULT NULL,禁止使用NULL字段 NULL字段很難查詢優化,NULL字段的索引需要額外空間,NULL字段的復合索引無效,詳情請查看:https://dev.mysql.com/doc/refman/5.7/en/problems-with-null.html
5.使用UNSIGNED存儲非負整數(存儲的范圍更大了)
6.關于datetime、timestamp類型的異同點。
相同點:
兩者的最小精度都為小數點后6位
不同點:
1)存儲范圍的問題:timestamp類型的存儲范圍較小,為’1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’ UTC;datetime類型的存儲范圍較大,為’1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’
2)時區的問題:timestamp會隨server端時區的變化而變化,datetime不會
8.建議使用VARCHAR存儲大小寫敏感的變長字符串
9.禁止在數據庫中存儲明文密碼,把密碼加密后存儲
10.不允許使用ENUM (插入非法值的時候,默認會插入一個空值)
11.所有的表(特殊情況除外,如:日志表)必須要有創建時間、更新時間兩列,前者表示主動創建,后者表示被動更新【強制】
create_time datetime(0) DEFAULT CURRENT_TIMESTAMP COMMENT ‘創建時間’
update_time datetime(0) DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT ‘更新時間’)
12.可以適當的添加冗余列,減少表關聯,提高查詢效率,通過注釋表明哪張是主表
13.多表關聯導致查詢語句性能低下,進行join不超過3個表。超過三個表禁止 join。需要 join 的字段,數據類型必須絕對一致;多表關聯查詢時, 保證被關聯的字段需要有索引。【強制】
說明:即使雙表join也要注意表索引、SQL 性能。
14.數據庫查詢語句where條件范圍要非常少,不要超過10條記錄返回。(建議)
15.業務數據表不允許包含數據物理硬刪除操作,若業務存在數據刪除操作需求,必須采用邏輯刪除,數據表中增加數據邏輯刪除標記is_deleted,確實需要進行物理刪除的時候需要經過部門leader同意后DBA方可操作。
(備注:其中is_deleted=’0’為否,is_deteled=’1’為是)
16.varchar 是可變長字符串,不預先分配存儲空間,長度不要超過5000,如果存儲長度大于此值,定義字段類型為text,獨立出來一張表,用主鍵來對應,避免影響其它字段索引效率。【強制】
17.合適的字符存儲長度,不但節約數據庫表空間、節約索引存儲,更重要的是提升檢 索速度。【參考】
18.對于內容重復的大字段如text、varchar(500)等列,可以新建冗余表,通過表關聯的方式進行查詢,提升查詢效率,減少磁盤空間使用。
四.索引規范
1.索引的數量要控制:
(1) 單個索引中的字段數不超過5個(建議3個以內)
(2) 單張表中索引數量不超過5個
2.主鍵準則
(1) 表必須有主鍵
(2) 不使用更新頻繁的列作為主鍵
(3) 盡量不選擇字符串列作為主鍵
(4) 不允許UUID MD5 HASH這些作為主鍵
(5) 默認使用非空的唯一鍵作為主鍵
(6) 建議選擇自增列作為主鍵,定義為 int/bigint unsigned auto_increment comment ‘主鍵’
3.重要的SQL必須被索引,比如:
(1) UPDATE.DELETE語句的WHERE條件列
(2) ORDER BY.GROUP BY.DISTINCT的字段
4.多表JOIN的字段注意以下(涉及到多表JOIN的需求,提前提交到DBA處審核):
(1) 區分度最大的字段放在前面
(2) 核心SQL優先考慮覆蓋索引
(3) 避免冗余和重復索引
(4) 索引要綜合評估數據密度和分布以及考慮查詢和更新比例
5.索引禁忌
(1) 不在低基數列上建立索引,例如“性別”
(2) 不在索引列進行數學運算和函數運算
(3) 創建索引前先查看表結構,避免創建冗余索引
(4) 在varchar字段上建立索引時,指定索引長度,沒必要對全字段建立索引,根據實際文本區分度決定索引長度即可。【建議】
說明:索引的長度與區分度是一對矛盾體,一般對字符串類型數據,區分度達到 90%及以上即可,可以使用 count(distinct left(列名, 索引長度))/count(distinct 列名)的區分度 來確定。
(5) 頁面搜索嚴禁左模糊或者全模糊,如果需要請走搜索引擎來解決。【強制】
說明:索引文件具有 B-Tree 的最左前綴匹配特性,如果左邊的值未確定,那么無法使用此索引。
(6) 建組合索引的時候,區分度最高的在最左邊。【強制】
正例:如果 where a=? and b=? ,如果 a 列的幾乎接近于唯一值,那么只需要單建 idx_a索引即可。
說明:存在非等號和等號混合時,在建索引時,請把等號條件的列前置。如:where c>? and d=? 那么即使 c 的區分度更高,也必須把 d 放在索引的最前列,即索引 idx_d_c。
6.盡量不使用外鍵
(1)不得使用外鍵與級聯,一切外鍵概念必須在應用層解決 【強制】
說明:以學生和成績的關系為例,學生表中的 student_id 是主鍵,那么成績表中的 student_id則為外鍵。如果更新學生表中的 student_id,同時觸發成績表中的student_id更新,即為 級聯更新。外鍵與級聯更新適用于單機低并發,不適合分布式、高并發集群;級聯更新是強阻塞,存在數據庫更新風暴的風險;外鍵影響數據庫的插入速度。
(2) 對父表和子表的操作會相互影響,降低可用性
7.索引命名:非唯一索引以 idx_字段1_字段2命名,唯一索引以uk_字段1_字段2命名,索引名稱必須全部小寫【建議】
8.新建的唯一索引必須不能和主鍵重復
9.索引字段的默認值不能為NULL,要改為其他的default或者空。NULL非常影響索引的查詢效率
10.反復查看與表相關的SQL,符合最左前綴的特點建立索引,例如:一個索引idx_test(n1,n2,n3),where n1= ;where n1= and n2=;where n1= and n3=;where n1= and n2= and n3=,這四種情況會使用到該索引。多條字段重復的語句,要修改語句條件字段的順序,為其建立一條聯合索引,減少索引數量。【強制】
11.能使用唯一索引就要使用唯一索引,提高查詢效率
12.使用EXPLAIN判斷SQL語句是否合理使用索引,盡量避免extra列出現:Using File Sort,Using Temporary
13.SQL變更需要確認索引是否需要變更并通知DBA
五.SQL規范
1.sql語句盡可能簡單,盡力避免使用JOIN
2.事務要簡單,整個事務的時間長度不要太長(多事務,小事務原則) ,單事務數據更改粒度為2000行,單事務提交時間應小于1S
3.避免使用觸發器.函數.存儲過程,如果臨時使用存儲過程進行批量操作,每個commit之后應該sleep 1s(根據情況設置),避免由于主庫大量寫入導致的主從延遲問題。
4.避免在數據庫中進行數學運算
5.在表查詢中,一律不要使用 * 作為查詢的字段列表,需要哪些字段必須明確寫明。
說明:
1)增加查詢分析器解析成本。
2)增減字段容易與resultMap配置不一致。
3)無用字段增加網絡消耗,尤其是text類型的字段。
6.limit分頁注意效率。Limit越大,效率越低。可以改寫limit,比如例子改寫:
select id from t limit 10000, 10;
=>
select id from t where id > 10000 limit 10;
SELECT * FROM table ORDER BY TIME DESC LIMIT 10000,10;
=>
SELECT * FROM table WHERE TIME<last_TIME ORDER BY TIME DESC LIMIT 10.
=>
SELECT * FROM table inner JOIN(SELECT id FROM table ORDER BY TIME LIMIT 10000,10) as t USING(id)
7.使用union all替代union
8.避免使用大表的JOIN
9.對數據的更新要打散后批量更新,不要一次更新太多數據,一次每次更新不超過2000條記錄
10.減少與數據庫的交互次數
11.注意使用性能分析工具 Sql explain / show profile
12.防止因字段類型不同造成的隱式轉換,導致索引失效。如id int,使用where id=‘1’;
13.IN條件里面的數據數量要少,盡量不用,IN條件里邊的數量應不超過20
14.能不用NOT IN就不用NOT IN,不會把NULL給查出來
15.在SQL語句中,禁止使用前綴是%的like
16.不使用負向查詢,如not in/like
17.關于分頁查詢:程序里建議合理使用分頁來提高效率limit,limit較大要配合子查詢使用
例如: 先快速定位需要獲取的id段,然后再關聯:
SELECT a.* FROM 表1 a, (select id from 表1 where 條件 LIMIT 100000,20 ) b where a.id=b.id
18.禁止在數據庫中跑大查詢
19.使用預編譯語句,只傳參數,比傳遞SQL語句更高效;一次解析,多次使用;降低SQL注入概率
20.禁止使用order by rand()
21.禁止單條SQL語句同時更新多個表
22.禁止子查詢中用group by,order by,DISTINCT。例如 (select xx,xxx from a where a.id in (select id from b group by xx)
23.對分區表查詢 條件中必須帶上分區字段
24.不要使用count(列名)或count(常量)來替count(),count()是SQL92定義的標準統計行數的語法,跟數據庫無關,跟NULL和非NULL無關。
說明:count(*)會統計值為NULL的行,而count(列名)不會統計此列為NULL值的行。
總結
以上是生活随笔為你收集整理的SQL——数据库使用规范(入门规范)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人生之路小游戏代码2
- 下一篇: SQL Server 2008服务器安装