MySQL 相關(guān)規(guī)范

流程規(guī)范

流程圖.jpg
  1. 服務(wù)正式上線前旭斥,一定要check下線上數(shù)據(jù)庫改動已經(jīng)上線悬包。不然會引起線上事故谊却!
  2. 測試環(huán)境也要有,不然測試環(huán)境后面會越來越難建設(shè)哑芹。

設(shè)計規(guī)范

規(guī)范共分為【強制】炎辨、【推薦】、【參考】三個等級聪姿,優(yōu)先級從高至低碴萧,如違反【強制】規(guī)范Reviewer應(yīng)當(dāng)打回。

命名規(guī)范

【強制】表的命名最好是“業(yè)務(wù)名稱_表的作用” 末购,無需額外的數(shù)據(jù)庫名開頭破喻。

對于bits數(shù)據(jù)庫來說,正例:app_build_config盟榴,workflow_job曹质; 反例:bits_app_info,bits_xxx擎场;

【強制】表名羽德、字段名必須使用小寫字母或****數(shù)字,禁止出現(xiàn)數(shù)字開頭迅办,禁止兩個下劃線中間只 出現(xiàn)數(shù)字宅静。正例:app_user,app_config站欺,level3_name 反例:AppUser姨夹,rdcConfig,level_3_name

【強制】表名使用單數(shù)矾策。 說明:表名應(yīng)該僅僅表示表里面的實體內(nèi)容磷账,不應(yīng)該表示實體數(shù)量,符合表達習(xí)慣贾虽。

【強制】索引名字的前綴必須idx_够颠,唯一約束/索引的前綴必須uk_

【強制】所有命名必須使用全名,有默認約定的除外榄鉴,如果超過 30 個字符履磨,使用縮寫

【強制】每個字段和表必須提供清晰的注釋蛉抓,現(xiàn)在沒有注釋 rds 不讓建表。


【推薦】庫的命名最好是“系統(tǒng)名稱_子系統(tǒng)名”剃诅, 正例 bits_pipeline巷送,bits_ttp。

字段規(guī)范

【強制】必加的三個字段

  • id(unsigned bigint)矛辕,單表時自增笑跛。防止枚舉時用id generator生成
  • create_time(timestamp),用于記錄主動創(chuàng)建時間聊品,默認值:current_timestamp
  • update_time(timestamp)飞蹂,用于記錄最后更新時間,默認值: current_timestamp

【強制】每個表不超過30個字段

【強制】如果存儲的字符串長度固定翻屈,使用 char 定長字符串類型

【強制】文本數(shù)據(jù)盡量用varchar 陈哑,變長存儲,更省存儲空間伸眶,長度不要超過 2700惊窖,如果存儲長 度大于此值,定義字段類型為 text厘贼,獨立出來一張表界酒,用主鍵來對應(yīng),避免影響其它字段索引效率嘴秸。

【強制】存儲字段如果為非負數(shù)毁欣,默認加上UNSIGNED。

【強制】小數(shù)類型為 decimal岳掐,禁止使用 float 和 double署辉。decimal不存在精度損失,數(shù)據(jù)類型decimal(p,s) 需要分別指定小數(shù)的最大位數(shù)(p)和小數(shù)位的數(shù)量(s)岩四。

【強制】如果修改字段含義或?qū)ψ侄伪硎镜臓顟B(tài)追加時哭尝,需要及時更新字段注釋。

【強制】業(yè)務(wù)中選擇性很少的狀態(tài)剖煌、****類型 等字段推薦使用 TINYINT材鹦。從1開始枚舉,并且將具體含義寫在字段備注里耕姊。禁止使用 bool 來存狀態(tài)桶唐。

【強制】索引字段不要設(shè)置為null

【強制】優(yōu)先選擇utf8mb4字符集,它的兼容性最好茉兰,而且還支持emoji字符尤泽。


【推薦】json 的數(shù)據(jù)使用 json 類型存儲而不是 text。MySQL 會幫我們做 json 格式校驗。注意長度限制坯约。(看業(yè)務(wù)場景)


【推薦】字段盡量設(shè)置為 NOT NULL熊咽, 為字段提供默認值。 如字符型的默認值為一個空字符串值闹丐;數(shù)值型默認值為數(shù)值 0横殴;邏輯型的默認值為數(shù)值 0;

【推薦】考慮業(yè)務(wù)場景,選擇軟硬刪除卿拴,必要的話衫仑,新增 delete_at,軟刪除堕花。

ToDo:補 GORM 和 build Tools @劉思齊 @劉濤

注意點:

  • count(*) 會統(tǒng)計NULL的行文狱, count(列名) 不會統(tǒng)計此列為NULL值的行

  • count(distinct col) 計算該列除 NULL 之外的不重復(fù)行數(shù),注意 count(distinct col1, col2) 如果其中一列全為 NULL缘挽,那么即使另一列有不同的值瞄崇,也返回為 0。

【推薦】遇到BLOB到踏、TEXT字段,則盡量拆出去尚猿,再用主鍵做關(guān)聯(lián)窝稿。超過4k大值拆出,考慮換存儲方案凿掂,主從延遲風(fēng)險伴榔。

【推薦】反范式設(shè)計:字段允許適當(dāng)冗余,以提高查詢性能庄萎。 如app表中的應(yīng)用名稱/應(yīng)用id等唯一鍵踪少,可以在別的業(yè)務(wù)表中均存儲一份,避免使用 join糠涛。

【推薦】時間類型采用為 timestamp 數(shù)據(jù)類型援奢,因為 datetime 占用 8 字節(jié),timestamp 僅占用4字節(jié)忍捡,范圍為 1970-01-01 00:00:012038-01-01 00:00:00


【參考】合適的字符存儲長度集漾,不但節(jié)約數(shù)據(jù)庫表空間、節(jié)約索引存儲砸脊,更重要的是提升檢索速度具篇。

類型(同義詞) 存儲長度(BYTES) 最小值(SIGNED/UNSIGNED) 最大值(SIGNED/UNSIGNED)
整型數(shù)字
TINYINT 1 -128/0 127/255
SMALLINT 2 -32,768/0 32767/65,535
MEDIUMINT 3 -8,388,608/0 8388607/16,777,215/
INT(INTEGER) 4 -2,14,7483,648/0 2147483647/4,294,967,295/
BIGINT 8 -2^63/0 263-1/264-1
時間類型
DATETIME 8 1001-01-01 00:00:00 9999-12-31 23:59:59
DATE 3 1001-01-01 9999-12-31
TIME 3 00:00:00 23:59:59
YEAR 1 1001 9999
TIMESTAMP 4 1970-01-01 00:00:00 2038-01-01 00:00:00

索引規(guī)范

【強制】表寫多讀少建議索引數(shù)不超過5個。表讀多寫少索引數(shù)不超過10個凌埂。

【強制】業(yè)務(wù)上具有唯一特性的字段驱显,即使是多個字段的組合,也必須建成唯一索引。

【強制】建議不使用 join埃疫。如果一定要使用伏恐,最多兩個表 join。需要 join 的字段熔恢,數(shù)據(jù)類型必須絕對一致;多表關(guān)聯(lián)查詢時脐湾, 保證被關(guān)聯(lián)的字段需要有索引。

【強制】在 varchar 字段上建立索引時叙淌,必須指定索引長度秤掌,沒必要對全字段建立索引,根據(jù) 實際文本區(qū)分度決定索引長度即可鹰霍。 說明:索引的長度與區(qū)分度是一對矛盾體闻鉴,一般對字符串類型數(shù)據(jù),長度為 20 的索引茂洒,區(qū)分度會高達 90%以上孟岛。

【強制】在建立索引時,多考慮建立聯(lián)合索引督勺,并把區(qū)分度最高的字段放在最前面渠羞。

【強制】模糊查詢僅允許右模糊 即“xxx%”,如果需要請走ES來解決智哀。

【強制】不要用外鍵次询,一切外鍵概念在應(yīng)用層解決。


【推薦】利用覆蓋索引來進行查詢操作瓷叫,避免回表屯吊。即 select b from tableA where a = 1

【推薦】如果選擇性超過 20%(區(qū)分度低于20%),那么全表掃描比使用索引性能更優(yōu)摹菠,即沒有設(shè)置索引的必要盒卸。

【推薦】防止因字段類型不同造成的隱式轉(zhuǎn)換,導(dǎo)致索引失效次氨。

【推薦】如果有 order by 的場景蔽介,請注意利用索引的有序性。order by 最后的字段是組合索引的一部分煮寡,并且放在索引組合順序的最后屉佳,避免出現(xiàn) file_sort 的情況,影響查詢性能洲押。

【推薦】不要對頻繁更新字段加索引


【參考】創(chuàng)建索引時避免有如下極端誤解

  • 錯誤一:寧濫勿缺武花。認為一個查詢就需要建一個索引。

  • 錯誤二:寧缺勿濫杈帐。認為索引會消耗空間体箕、嚴重拖慢更新和新增速度专钉。

  • 錯誤三:抵制惟一索引。認為業(yè)務(wù)的惟一性一律需要在應(yīng)用層通過“先查后插”方式解決累铅。

使用規(guī)范

【強制】用Explain來做SQL 性能優(yōu)化跃须,type 至少要達到 range 級別,要求是 ref 級別娃兽,如果可以是 consts 最好

描述
system The table has only one row (= system table). This is a special case of the const join type.
const The table has at most one matching row, which is read at the start of the query. Because there is only one row, values from the column in this row can be regarded as constants by the rest of the optimizer. const tables are very fast because they are read only once.
eq_ref One row is read from this table for each combination of rows from the previous tables. Other than the system and const types, this is the best possible join type. It is used when all parts of an index are used by the join and the index is a PRIMARY KEY or UNIQUE NOT NULL index.
ref All rows with matching index values are read from this table for each combination of rows from the previous tables. ref is used if the join uses only a leftmost prefix of the key or if the key is not a PRIMARY KEY or UNIQUE index (in other words, if the join cannot select a single row based on the key value). If the key that is used matches only a few rows, this is a good join type.
fulltext The join is performed using a FULLTEXT index.
ref_or_null This join type is like ref, but with the addition that MySQL does an extra search for rows that contain NULL values. This join type optimization is used most often in resolving subqueries. In the following examples, MySQL can use a ref_or_null join to process ref_table:
index_merge This join type indicates that the Index Merge optimization is used. In this case, the key column in the output row contains a list of indexes used, and key_len contains a list of the longest key parts for the indexes used
unique_subquery This type replaces eq_ref for some IN subqueries of the following form:
index_subquery This join type is similar to unique_subquery. It replaces IN subqueries, but it works for nonunique indexes in subqueries of the following form
range Only rows that are in a given range are retrieved, using an index to select the rows. The key column in the output row indicates which index is used. The key_len contains the longest key part that was used. The ref column is NULL for this type.
index The index join type is the same as ALL, except that the index tree is scanned. This occurs two ways:
- If the index is a covering index for the queries and can be used to satisfy all data required from the table, only the index tree is scanned. In this case, the Extra column says Using index. An index-only scan usually is faster than ALL because the size of the index usually is smaller than the table data.
-A full table scan is performed using reads from the index to look up data rows in index order. Uses index does not appear in the Extra column.
-MySQL can use this join type when the query uses only columns that are part of a single index.
ALL A full table scan is done for each combination of rows from the previous tables. This is normally not good if the table is the first table not marked const, and usually very bad in all other cases. Normally, you can avoid ALL by adding indexes that enable row retrieval from the table based on constant values or column values from earlier tables.

【強制】不要使用 count(列名)或 count(常量)來替代 count()菇民,count()是 SQL92 定義的 標準統(tǒng)計行數(shù)的語法,跟數(shù)據(jù)庫無關(guān)投储,跟 NULL 和非 NULL 無關(guān)第练。

  • count(*)會統(tǒng)計值為 NULL 的行,而 count(列名)不會統(tǒng)計此列為 NULL 值的行玛荞。

【強制】連表查詢的情況下娇掏,要確保關(guān)聯(lián)條件的數(shù)據(jù)類型一致,避免嵌套

【強制】使用 ISNULL()來判斷是否為 NULL 值勋眯。 說明:NULL 與任何值的直接比較都為 NULL婴梧。

  • NULL<>NULL的返回結(jié)果是NULL,而不是false客蹋。

  • NULL=NULL的返回結(jié)果是NULL塞蹭,而不是true。

  • NULL<>1的返回結(jié)果是NULL讶坯,而不是true番电。

【強制】查詢時不要對索引列做計算/使用函數(shù)。避免索引列的類型轉(zhuǎn)換以及字符串編碼轉(zhuǎn)換闽巩。

【強制】更新數(shù)據(jù)超過1000條的update钧舌,delete和insert語句担汤,需要改成分批量多次更新來進行

【強制】禁止使用存儲過程涎跨,視圖,觸發(fā)器崭歧,event等高級特性

【強制】in子句中的值不要超過500個

【強制】提RDS DML工單時隅很,update or delete 的長度確定時,加上 limit <行數(shù)>率碾。這樣就算提的工單 DML SQL寫錯了叔营,錯誤造成的影響也可控。(降低工單造成的事故風(fēng)險)

【強制】提工單的時候備注背景寫一下所宰。


【推薦】不建議使用子查詢绒尊,建議將子查詢 SQL 拆開結(jié)合程序多次查詢。

【推薦】不要對索引字段使用負向查詢仔粥,比如not in,not like

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婴谱,一起剝皮案震驚了整個濱河市蟹但,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谭羔,老刑警劉巖华糖,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異瘟裸,居然都是意外死亡客叉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進店門话告,熙熙樓的掌柜王于貴愁眉苦臉地迎上來兼搏,“玉大人,你說我怎么就攤上這事超棺∠蜃澹” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵棠绘,是天一觀的道長件相。 經(jīng)常有香客問我,道長氧苍,這世上最難降的妖魔是什么夜矗? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮让虐,結(jié)果婚禮上紊撕,老公的妹妹穿的比我還像新娘。我一直安慰自己赡突,他們只是感情好对扶,可當(dāng)我...
    茶點故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惭缰,像睡著了一般浪南。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上漱受,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天络凿,我揣著相機與錄音,去河邊找鬼昂羡。 笑死絮记,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的虐先。 我是一名探鬼主播怨愤,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蛹批!你這毒婦竟也來了撰洗?” 一聲冷哼從身側(cè)響起膀息,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎了赵,沒想到半個月后潜支,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡柿汛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年冗酿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片络断。...
    茶點故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡裁替,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出貌笨,到底是詐尸還是另有隱情弱判,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布锥惋,位于F島的核電站昌腰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏膀跌。R本人自食惡果不足惜遭商,卻給世界環(huán)境...
    茶點故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捅伤。 院中可真熱鬧劫流,春花似錦、人聲如沸丛忆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熄诡。三九已至可很,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粮彤,已是汗流浹背根穷。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工姜骡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留导坟,地道東北人。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓圈澈,卻偏偏與公主長得像惫周,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子康栈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,925評論 2 344

推薦閱讀更多精彩內(nèi)容

  • MySQL索引原理 索引目的 索引的目的在于提高查詢效率递递,可以類比字典喷橙,如果要查“mysql”這個單詞,我們肯定需...
    cutieagain閱讀 334評論 0 0
  • Mysql相關(guān) Mysql并發(fā)控制-鎖 共享鎖 共享鎖也稱為讀鎖登舞,讀鎖允許多個連接可以同一時刻并發(fā)的讀取同一資源贰逾,...
    萬福來閱讀 230評論 0 0
  • 前言 關(guān)于前面講過的知識點我就不再贅述了,還沒看過的朋友可以進入我的首頁進行查閱(前言部分附贈飛機票)菠秒。這篇文章將...
    6曦軒閱讀 548評論 0 0
  • M ysql索引用來快速地尋找那些具有特定值的記錄疙剑,所有MySQL索引都以B-樹的形式保存。如果沒有索引践叠,執(zhí)行查詢...
    脆皮雞大蝦閱讀 204評論 0 0
  • 1言缤、幾種主要的數(shù)據(jù)庫引擎的區(qū)別 MyISAM讀取操作速度很快,而且不占用大量的內(nèi)存和存儲資源禁灼,但是不支持事務(wù)和外鍵...
    小胖六閱讀 510評論 1 2