數(shù)據(jù)庫使用規(guī)范

關(guān)于庫:

【強制】庫的名稱必須控制在32個字符以內(nèi)蓖救,英文一律小寫。

【強制】庫的名稱格式:業(yè)務(wù)系統(tǒng)名稱_子系統(tǒng)名。

【強制】庫名只能使用英文字母豫喧,數(shù)字舆蝴,下劃線谦絮,并以英文字母開頭。

【強制】創(chuàng)建數(shù)據(jù)庫時必須顯式指定字符集洁仗,并且字符集只能是utf8或者utf8mb4层皱。創(chuàng)建數(shù)據(jù)庫SQL舉例:Create database db1 default character set utf8;

【建議】臨時庫、表名以tmp_ 為前綴赠潦,并以日期為后綴叫胖,備份庫、表以 bak_ 為前綴她奥,并以日期為后綴瓮增。

關(guān)于表:

【強制】表和列的名稱必須控制在32個字符以內(nèi),表名只能使用字母哩俭、數(shù)字和下劃線绷跑,一律小寫。

【強制】表名要求模塊名強相關(guān)凡资,同一模塊使用的表名盡量使用統(tǒng)一前綴砸捏。

【強制】創(chuàng)建表時必須顯式指定字符集為utf8或utf8mb4。

【強制】列名盡量不用關(guān)鍵字(如type,order等)隙赁。

【強制】創(chuàng)建表時必須顯式指定表存儲引擎類型垦藏,如無特殊需求,一律為InnoDB伞访。

【強制】建表必須有comment掂骏。

【強制】對于超過100W行的大表進行alter table,必須經(jīng)過DBA審核厚掷,并在業(yè)務(wù)低峰期執(zhí)行弟灼,多個alter需整合在一起级解。

因為alter table會產(chǎn)生表鎖,期間阻塞對于該表的所有寫入袜爪,對于業(yè)務(wù)可能會產(chǎn)生極大影響蠕趁。

【建議】建表時關(guān)于主鍵:表必須有主鍵

(1)強制要求主鍵為id,類型為int或bigint辛馆,且為auto_increment 建議使用unsigned無符號型俺陋。

(2)標(biāo)識表里每一行主體的字段不要設(shè)為主鍵,建議設(shè)為其他字段如user_id昙篙,order_id等腊状,并建立unique key索引。

因為如果設(shè)為主鍵且主鍵值為隨機插入苔可,則會導(dǎo)致innodb內(nèi)部page分裂和大量隨機I/O缴挖,性能下降。

【建議】核心表(如用戶表)必須有行數(shù)據(jù)的創(chuàng)建時間字段create_time和最后更新時間字段update_time焚辅,便于查問題映屋。

【建議】表中所有字段盡量都是NOT NULL屬性,業(yè)務(wù)可以根據(jù)需要定義DEFAULT值同蜻。

因為使用NULL值會存在每一行都會占用額外存儲空間棚点、數(shù)據(jù)遷移容易出錯、聚合函數(shù)計算結(jié)果偏差等問題湾蔓。

【建議】中間表用于保留中間結(jié)果集瘫析,名稱必須以tmp_ 開頭。備份表用于備份或抓取源表快照默责,名稱必須以bak_開頭贬循。中間表和備份表定期清理桃序。

【示范】一個較為規(guī)范的建表語句:


CREATE TABLE user_info (

  `id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',

  `user_id` bigint(11) NOT NULL COMMENT '用戶id',

  `username` varchar(45) NOT NULL COMMENT '真實姓名',

  `email` varchar(30) NOT NULL COMMENT '用戶郵箱',

  `nickname` varchar(45) NOT NULL COMMENT '昵稱',

  `birthday` date NOT NULL COMMENT '生日',

  `sex` tinyint(4) DEFAULT '0' COMMENT '性別',

  `short_introduce` varchar(150) DEFAULT NULL COMMENT '一句話介紹自己亏掀,最多50個漢字',

  `user_resume` varchar(300) NOT NULL COMMENT '用戶提交的簡歷存放地址',

  `user_register_ip` int NOT NULL COMMENT '用戶注冊時的源ip',

  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',

  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間',

  `user_review_status` tinyint NOT NULL COMMENT '用戶資料審核狀態(tài),1為通過泛释,2為審核中怜校,3為未通過茄茁,4為還未提交審核',

  PRIMARY KEY (`id`),

  UNIQUE KEY `uniq_user_id` (`user_id`),

  KEY `idx_username`(`username`),

  KEY `idx_create_time_status`(`create_time`,`user_review_status`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='網(wǎng)站用戶基本信息'

關(guān)于索引:

【強制】InnoDB表必須主鍵為id int/bigint auto_increment,且主鍵值禁止被更新付燥。

【強制】InnoDB和MyISAM存儲引擎表键科,索引類型必須為BTREE勋颖。

【建議】主鍵的名稱以 pk_ 開頭饭玲,唯一鍵以 uniq_ 或 uk_ 開頭茄厘,普通索引以 idx_ 開頭次哈,一律使用小寫格式亿乳,以字段的名稱或縮寫作為后綴葛假。

【建議】單個表上的索引個數(shù)不能超過8個聊训。

【建議】在建立索引時带斑,多考慮建立聯(lián)合索引,并把區(qū)分度最高的字段放在最前面挂滓。如列userid的區(qū)分度可由select count(distinct userid)計算出來赶站。

【建議】在多表join的SQL里贝椿,保證被驅(qū)動表的連接列上有索引瑟蜈,這樣join執(zhí)行效率最高踪栋。

【建議】建表或加索引時,保證表里互相不存在冗余索引囤官。

對于MySQL來說党饮,如果表里已經(jīng)存在key(a,b),則key(a)為冗余索引蹲堂,需要刪除。

SQL編寫:

【強制】程序端SELECT語句必須指定具體字段名稱朽基,禁止寫成 *。

【強制】程序端insert語句指定具體字段名稱霎俩,不要寫成insert into t1 values(…)。

【強制】除靜態(tài)表或小表(100行以內(nèi))学密,DML語句必須有where條件腻暮,且使用索引查找。

【強制】where條件里等號左右字段類型必須一致毯侦,否則無法利用索引哭靖。

【強制】WHERE 子句中禁止只使用全模糊的LIKE條件進行查找试幽,必須有其他等值或范圍查詢條件卦碾,否則無法利用索引。

【強制】索引列不要使用函數(shù)或表達式,否則無法利用索引。如where length(name)='Admin'或where user_id+2=10023钝诚。

【建議】insert into…values(XX),(XX),(XX).. 這里XX的值不要超過5000個疹鳄。

值過多雖然上線很很快拧略,但會引起主從同步延遲。

【建議】SELECT語句不要使用UNION瘪弓,推薦使用UNION ALL袱饭,并且UNION子句個數(shù)限制在5個以內(nèi)川无。

因為union all不需要去重,節(jié)省數(shù)據(jù)庫資源虑乖,提高性能懦趋。

【強制】禁止跨db的join語句。

【建議】不建議使用子查詢疹味,建議將子查詢SQL拆開結(jié)合程序多次查詢仅叫,或使用join來代替子查詢。

【建議】線上環(huán)境糙捺,多表join不要超過5個表诫咱。

【建議】在多表join中,盡量選取結(jié)果集較小的表作為驅(qū)動表洪灯,來join其他表坎缭。

【建議】批量操作數(shù)據(jù)時,需要控制事務(wù)處理間隔時間婴渡,進行必要的sleep幻锁。

建議】事務(wù)里包含SQL不超過5個

因為過長的事務(wù)會導(dǎo)致鎖數(shù)據(jù)較久,MySQL內(nèi)部緩存边臼、連接消耗過多等問題哄尔。

【建議】事務(wù)里更新語句盡量基于主鍵或unique key,如update … where id=XX;

否則會產(chǎn)生間隙鎖柠并,內(nèi)部擴大鎖定范圍岭接,導(dǎo)致系統(tǒng)性能下降,產(chǎn)生死鎖臼予。

【建議】減少使用order by鸣戴,和業(yè)務(wù)溝通能不排序就不排序,或?qū)⑴判蚍诺匠绦蚨巳プ稣呈啊rder by窄锅、group by、distinct這些語句較為耗費CPU缰雇,數(shù)據(jù)庫的CPU資源是極其寶貴的入偷。

【建議】order by、group by械哟、distinct這些SQL盡量利用索引直接檢索出排序好的數(shù)據(jù)疏之。如where a=1 order by b可以利用key(a,b)。

【建議】包含了order by暇咆、group by锋爪、distinct這些查詢的語句丙曙,where條件過濾出來的結(jié)果集請保持在1000行以內(nèi),否則SQL會很慢其骄。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亏镰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拯爽,更是在濱河造成了極大的恐慌拆挥,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件某抓,死亡現(xiàn)場離奇詭異,居然都是意外死亡惰瓜,警方通過查閱死者的電腦和手機否副,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崎坊,“玉大人备禀,你說我怎么就攤上這事∧巫幔” “怎么了曲尸?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長男翰。 經(jīng)常有香客問我另患,道長,這世上最難降的妖魔是什么蛾绎? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任昆箕,我火速辦了婚禮,結(jié)果婚禮上租冠,老公的妹妹穿的比我還像新娘鹏倘。我一直安慰自己,他們只是感情好顽爹,可當(dāng)我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布纤泵。 她就那樣靜靜地躺著,像睡著了一般镜粤。 火紅的嫁衣襯著肌膚如雪捏题。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天繁仁,我揣著相機與錄音涉馅,去河邊找鬼。 笑死黄虱,一個胖子當(dāng)著我的面吹牛稚矿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼晤揣,長吁一口氣:“原來是場噩夢啊……” “哼桥爽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起昧识,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤钠四,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后跪楞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缀去,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年甸祭,在試婚紗的時候發(fā)現(xiàn)自己被綠了缕碎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡池户,死狀恐怖咏雌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情校焦,我是刑警寧澤赊抖,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站寨典,受9級特大地震影響氛雪,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜耸成,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一注暗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧墓猎,春花似錦捆昏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至左胞,卻和暖如春寇仓,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背烤宙。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工遍烦, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人躺枕。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓服猪,卻偏偏與公主長得像供填,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子罢猪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,512評論 2 359