MySQL數(shù)據(jù)庫設(shè)計(jì)規(guī)范

目錄

1. 規(guī)范背景與目的
2. 設(shè)計(jì)規(guī)范
2.1 數(shù)據(jù)庫設(shè)計(jì)
2.1.1 庫名
2.1.2 表結(jié)構(gòu)
2.1.3 列數(shù)據(jù)類型優(yōu)化
2.1.4 索引設(shè)計(jì)
2.1.5 分庫分表瓢娜、分區(qū)表
2.1.6 字符集
2.1.7 程序DAO層設(shè)計(jì)建議
2.1.8 一個(gè)規(guī)范的建表語句示例
2.2 SQL編寫
2.2.1 DML語句
2.2.2 多表連接
2.2.3 事務(wù)
2.2.4 排序和分組
2.2.5 線上禁止使用的SQL語句</pre>

1. 規(guī)范背景與目的

MySQL數(shù)據(jù)庫與 Oracle圈驼、 SQL Server 等數(shù)據(jù)庫相比滓鸠,有其內(nèi)核上的優(yōu)勢與劣勢。我們在使用MySQL數(shù)據(jù)庫的時(shí)候需要遵循一定規(guī)范动漾,揚(yáng)長避短膀曾。本規(guī)范旨在幫助或指導(dǎo)RD酒唉、QA、OP等技術(shù)人員做出適合線上業(yè)務(wù)的數(shù)據(jù)庫設(shè)計(jì)委乌。在數(shù)據(jù)庫變更和處理流程床牧、數(shù)據(jù)庫表設(shè)計(jì)、SQL編寫等方面予以規(guī)范遭贸,從而為公司業(yè)務(wù)系統(tǒng)穩(wěn)定戈咳、健康地運(yùn)行提供保障。

2. 設(shè)計(jì)規(guī)范

2.1 數(shù)據(jù)庫設(shè)計(jì)

以下所有規(guī)范會(huì)按照【高魏敬担】著蛙、【強(qiáng)制】、【建議】三個(gè)級(jí)別進(jìn)行標(biāo)注耳贬,遵守優(yōu)先級(jí)從高到低踏堡。

對(duì)于不滿足【高危】和【強(qiáng)制】兩個(gè)級(jí)別的設(shè)計(jì)效拭,DBA會(huì)強(qiáng)制打回要求修改暂吉。

2.1.1 庫名

  1. 【強(qiáng)制】庫的名稱必須控制在32個(gè)字符以內(nèi),相關(guān)模塊的表名與表名之間盡量提現(xiàn)join的關(guān)系缎患,如user表和user_login表慕的。

  2. 【強(qiáng)制】庫的名稱格式:業(yè)務(wù)系統(tǒng)名稱_子系統(tǒng)名,同一模塊使用的表名盡量使用統(tǒng)一前綴挤渔。

  3. 【強(qiáng)制】一般分庫名稱命名格式是庫通配名_編號(hào)肮街,編號(hào)從0開始遞增,比如wenda_001以時(shí)間進(jìn)行分庫的名稱格式是“庫通配名_時(shí)間”

  4. 【強(qiáng)制】創(chuàng)建數(shù)據(jù)庫時(shí)必須顯式指定字符集判导,并且字符集只能是utf8或者utf8mb4嫉父。創(chuàng)建數(shù)據(jù)庫SQL舉例:create database db1 default character set utf8;

2.1.2 表結(jié)構(gòu)

  1. 【強(qiáng)制】表和列的名稱必須控制在32個(gè)字符以內(nèi)眼刃,表名只能使用字母绕辖、數(shù)字和下劃線,一律小寫擂红。

  2. 【強(qiáng)制】表名要求模塊名強(qiáng)相關(guān)仪际,如師資系統(tǒng)采用”sz”作為前綴,渠道系統(tǒng)采用”qd”作為前綴等。

  3. 【強(qiáng)制】創(chuàng)建表時(shí)必須顯式指定字符集為utf8或utf8mb4树碱。

  4. 【強(qiáng)制】創(chuàng)建表時(shí)必須顯式指定表存儲(chǔ)引擎類型肯适,如無特殊需求,一律為InnoDB成榜。當(dāng)需要使用除InnoDB/MyISAM/Memory以外的存儲(chǔ)引擎時(shí)框舔,必須通過DBA審核才能在生產(chǎn)環(huán)境中使用。因?yàn)镮nnodb表支持事務(wù)赎婚、行鎖刘绣、宕機(jī)恢復(fù)、MVCC等關(guān)系型數(shù)據(jù)庫重要特性惑淳,為業(yè)界使用最多的MySQL存儲(chǔ)引擎额港。而這是其他大多數(shù)存儲(chǔ)引擎不具備的,因此首推InnoDB歧焦。

  5. 【強(qiáng)制】建表必須有comment

  6. 【建議】建表時(shí)關(guān)于主鍵:(1)強(qiáng)制要求主鍵為id移斩,類型為int或bigint,且為auto_increment(2)標(biāo)識(shí)表里每一行主體的字段不要設(shè)為主鍵绢馍,建議設(shè)為其他字段如user_id向瓷,order_id等,并建立unique key索引(可參考cdb.teacher表設(shè)計(jì))舰涌。因?yàn)槿绻O(shè)為主鍵且主鍵值為隨機(jī)插入猖任,則會(huì)導(dǎo)致innodb內(nèi)部page分裂和大量隨機(jī)I/O,性能下降瓷耙。

  7. 【建議】核心表(如用戶表朱躺,金錢相關(guān)的表)必須有行數(shù)據(jù)的創(chuàng)建時(shí)間字段create_time和最后更新時(shí)間字段update_time,便于查問題搁痛。

  8. 【建議】表中所有字段必須都是NOT NULL屬性长搀,業(yè)務(wù)可以根據(jù)需要定義DEFAULT值。因?yàn)槭褂肗ULL值會(huì)存在每一行都會(huì)占用額外存儲(chǔ)空間鸡典、數(shù)據(jù)遷移容易出錯(cuò)源请、聚合函數(shù)計(jì)算結(jié)果偏差等問題。

  9. 【建議】建議對(duì)表里的blob彻况、text等大字段谁尸,垂直拆分到其他表里,僅在需要讀這些對(duì)象的時(shí)候才去select纽甘。

  10. 【建議】反范式設(shè)計(jì):把經(jīng)常需要join查詢的字段良蛮,在其他表里冗余一份。如user_name屬性在user_account悍赢,user_login_log等表里冗余一份背镇,減少join查詢咬展。

  11. 【強(qiáng)制】中間表用于保留中間結(jié)果集,名稱必須以tmp_開頭瞒斩。備份表用于備份或抓取源表快照,名稱必須以bak_開頭涮总。中間表和備份表定期清理胸囱。

  12. 【強(qiáng)制】對(duì)于超過100W行的大表進(jìn)行alter table,必須經(jīng)過DBA審核瀑梗,并在業(yè)務(wù)低峰期執(zhí)行烹笔。因?yàn)?code>alter table會(huì)產(chǎn)生表鎖,期間阻塞對(duì)于該表的所有寫入抛丽,對(duì)于業(yè)務(wù)可能會(huì)產(chǎn)生極大影響谤职。

2.1.3 列數(shù)據(jù)類型優(yōu)化

  1. 【建議】表中的自增列(auto_increment屬性),推薦使用bigint類型亿鲜。因?yàn)闊o符號(hào)int存儲(chǔ)范圍為-2147483648~2147483647(大約21億左右)允蜈,溢出后會(huì)導(dǎo)致報(bào)錯(cuò)。

  2. 【建議】業(yè)務(wù)中選擇性很少的狀態(tài)status蒿柳、類型type等字段推薦使用tinytint或者smallint類型節(jié)省存儲(chǔ)空間饶套。

  3. 【建議】業(yè)務(wù)中IP地址字段推薦使用int類型,不推薦用char(15)垒探。因?yàn)?code>int只占4字節(jié)妓蛮,可以用如下函數(shù)相互轉(zhuǎn)換,而char(15)占用至少15字節(jié)圾叼。一旦表數(shù)據(jù)行數(shù)到了1億蛤克,那么要多用1.1G存儲(chǔ)空間。SQL:select inet_aton('192.168.2.12'); select inet_ntoa(3232236044); PHP: ip2long(‘192.168.2.12’); long2ip(3530427185);

  4. 【建議】不推薦使用enum夷蚊,set构挤。因?yàn)樗鼈兝速M(fèi)空間,且枚舉值寫死了撬码,變更不方便儿倒。推薦使用tinyintsmallint

  5. 【建議】不推薦使用blob呜笑,text等類型夫否。它們都比較浪費(fèi)硬盤和內(nèi)存空間。在加載表數(shù)據(jù)時(shí)叫胁,會(huì)讀取大字段到內(nèi)存里從而浪費(fèi)內(nèi)存空間凰慈,影響系統(tǒng)性能。建議和PM驼鹅、RD溝通微谓,是否真的需要這么大字段森篷。Innodb中當(dāng)一行記錄超過8098字節(jié)時(shí),會(huì)將該記錄中選取最長的一個(gè)字段將其768字節(jié)放在原始page里豺型,該字段余下內(nèi)容放在overflow-page里仲智。不幸的是在compact行格式下,原始pageoverflow-page都會(huì)加載姻氨。

  6. 【建議】存儲(chǔ)金錢的字段钓辆,建議用int,程序端乘以100和除以100進(jìn)行存取肴焊。因?yàn)?code>int占用4字節(jié)前联,而double占用8字節(jié),空間浪費(fèi)娶眷。

  7. 【建議】文本數(shù)據(jù)盡量用varchar存儲(chǔ)似嗤。因?yàn)?code>varchar是變長存儲(chǔ),比char更省空間届宠。MySQL server層規(guī)定一行所有文本最多存65535字節(jié)烁落,因此在utf8字符集下最多存21844個(gè)字符,超過會(huì)自動(dòng)轉(zhuǎn)換為mediumtext字段席揽。而text在utf8字符集下最多存21844個(gè)字符顽馋,mediumtext最多存224/3個(gè)字符,`longtext`最多存232個(gè)字符幌羞。一般建議用varchar類型寸谜,字符數(shù)不要超過2700。

  8. 【建議】時(shí)間類型盡量選取timestamp属桦。因?yàn)?code>datetime占用8字節(jié)熊痴,timestamp僅占用4字節(jié),但是范圍為1970-01-01 00:00:012038-01-01 00:00:00聂宾。更為高階的方法果善,選用int來存儲(chǔ)時(shí)間,使用SQL函數(shù)unix_timestamp()from_unixtime()來進(jìn)行轉(zhuǎn)換系谐。

詳細(xì)存儲(chǔ)大小參加下圖:

image

2.1.4 索引設(shè)計(jì)

  1. 【強(qiáng)制】InnoDB表必須主鍵為id int/bigint auto_increment,且主鍵值禁止被更新巾陕。

  2. 【建議】主鍵的名稱以“pk_”開頭,唯一鍵以“uk_”或“uq_”開頭纪他,普通索引以“idx_”開頭鄙煤,一律使用小寫格式,以表名/字段的名稱或縮寫作為后綴茶袒。

  3. 【強(qiáng)制】InnoDB和MyISAM存儲(chǔ)引擎表梯刚,索引類型必須為BTREE;MEMORY表可以根據(jù)需要選擇HASH或者BTREE類型索引薪寓。

  4. 【強(qiáng)制】單個(gè)索引中每個(gè)索引記錄的長度不能超過64KB亡资。

  5. 【建議】單個(gè)表上的索引個(gè)數(shù)不能超過7個(gè)澜共。

  6. 【建議】在建立索引時(shí),多考慮建立聯(lián)合索引锥腻,并把區(qū)分度最高的字段放在最前面嗦董。如列userid的區(qū)分度可由select count(distinct userid)計(jì)算出來。

  7. 【建議】在多表join的SQL里旷太,保證被驅(qū)動(dòng)表的連接列上有索引展懈,這樣join執(zhí)行效率最高。

  8. 【建議】建表或加索引時(shí)供璧,保證表里互相不存在冗余索引。對(duì)于MySQL來說冻记,如果表里已經(jīng)存在key(a,b)睡毒,則key(a)為冗余索引,需要?jiǎng)h除冗栗。

2.1.5 分庫分表演顾、分區(qū)表

  1. 【強(qiáng)制】分區(qū)表的分區(qū)字段(partition-key)必須有索引,或者是組合索引的首列隅居。

  2. 【強(qiáng)制】單個(gè)分區(qū)表中的分區(qū)(包括子分區(qū))個(gè)數(shù)不能超過1024钠至。

  3. 【強(qiáng)制】上線前RD或者DBA必須指定分區(qū)表的創(chuàng)建、清理策略胎源。

  4. 【強(qiáng)制】訪問分區(qū)表的SQL必須包含分區(qū)鍵棉钧。

  5. 【建議】單個(gè)分區(qū)文件不超過2G,總大小不超過50G涕蚤。建議總分區(qū)數(shù)不超過20個(gè)宪卿。

  6. 【強(qiáng)制】對(duì)于分區(qū)表執(zhí)行alter table操作,必須在業(yè)務(wù)低峰期執(zhí)行万栅。

  7. 【強(qiáng)制】采用分庫策略的佑钾,庫的數(shù)量不能超過1024

  8. 【強(qiáng)制】采用分表策略的,表的數(shù)量不能超過4096

  9. 【建議】單個(gè)分表不超過500W行烦粒,ibd文件大小不超過2G休溶,這樣才能讓數(shù)據(jù)分布式變得性能更佳。

  10. 【建議】水平分表盡量用取模方式扰她,日志兽掰、報(bào)表類數(shù)據(jù)建議采用日期進(jìn)行分表。

2.1.6 字符集

  1. 【強(qiáng)制】數(shù)據(jù)庫本身庫义黎、表禾进、列所有字符集必須保持一致,為utf8utf8mb4廉涕。

  2. 【強(qiáng)制】前端程序字符集或者環(huán)境變量中的字符集泻云,與數(shù)據(jù)庫艇拍、表的字符集必須一致,統(tǒng)一為utf8宠纯。

2.1.7 程序?qū)覦AO設(shè)計(jì)建議

  1. 【建議】新的代碼不要用model卸夕,推薦使用手動(dòng)拼SQL+綁定變量傳入?yún)?shù)的方式。因?yàn)閙odel雖然可以使用面向?qū)ο蟮姆绞讲僮鱠b婆瓜,但是其使用不當(dāng)很容易造成生成的SQL非常復(fù)雜快集,且model層自己做的強(qiáng)制類型轉(zhuǎn)換性能較差,最終導(dǎo)致數(shù)據(jù)庫性能下降廉白。

  2. 【建議】前端程序連接MySQL或者redis个初,必須要有連接超時(shí)和失敗重連機(jī)制,且失敗重試必須有間隔時(shí)間猴蹂。

  3. 【建議】前端程序報(bào)錯(cuò)里盡量能夠提示MySQL或redis原生態(tài)的報(bào)錯(cuò)信息院溺,便于排查錯(cuò)誤。

  4. 【建議】對(duì)于有連接池的前端程序磅轻,必須根據(jù)業(yè)務(wù)需要配置初始珍逸、最小、最大連接數(shù)聋溜,超時(shí)時(shí)間以及連接回收機(jī)制谆膳,否則會(huì)耗盡數(shù)據(jù)庫連接資源,造成線上事故撮躁。

  5. 【建議】對(duì)于log或history類型的表漱病,隨時(shí)間增長容易越來越大,因此上線前RD或者DBA必須建立表數(shù)據(jù)清理或歸檔方案馒胆。

  6. 【建議】在應(yīng)用程序設(shè)計(jì)階段缨称,RD必須考慮并規(guī)避數(shù)據(jù)庫中主從延遲對(duì)于業(yè)務(wù)的影響。盡量避免從庫短時(shí)延遲(20秒以內(nèi))對(duì)業(yè)務(wù)造成影響祝迂,建議強(qiáng)制一致性的讀開啟事務(wù)走主庫睦尽,或更新后過一段時(shí)間再去讀從庫。

  7. 【建議】多個(gè)并發(fā)業(yè)務(wù)邏輯訪問同一塊數(shù)據(jù)(innodb表)時(shí)型雳,會(huì)在數(shù)據(jù)庫端產(chǎn)生行鎖甚至表鎖導(dǎo)致并發(fā)下降当凡,因此建議更新類SQL盡量基于主鍵去更新。

  8. 【建議】業(yè)務(wù)邏輯之間加鎖順序盡量保持一致纠俭,否則會(huì)導(dǎo)致死鎖沿量。

  9. 【建議】對(duì)于單表讀寫比大于10:1的數(shù)據(jù)行或單個(gè)列,可以將熱點(diǎn)數(shù)據(jù)放在緩存里(如mecache或redis)冤荆,加快訪問速度朴则,降低MySQL壓力。

2.1.8 一個(gè)規(guī)范的建表語句示例

一個(gè)較為規(guī)范的建表語句為:

<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="" cid="n135" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">CREATE TABLE user ( id bigint(11) NOT NULL AUTO_INCREMENT, user_id bigint(11) NOT NULL COMMENT ‘用戶id’ username varchar(45) NOT NULL COMMENT '真實(shí)姓名', email varchar(30) NOT NULL COMMENT ‘用戶郵箱’, nickname varchar(45) NOT NULL COMMENT '昵稱', avatar int(11) NOT NULL COMMENT '頭像', birthday date NOT NULL COMMENT '生日', sex tinyint(4) DEFAULT '0' COMMENT '性別', short_introduce varchar(150) DEFAULT NULL COMMENT '一句話介紹自己钓简,最多50個(gè)漢字', user_resume varchar(300) NOT NULL COMMENT '用戶提交的簡歷存放地址', user_register_ip int NOT NULL COMMENT ‘用戶注冊時(shí)的源ip’, create_time timestamp NOT NULL COMMENT ‘用戶記錄創(chuàng)建的時(shí)間’, update_time timestamp NOT NULL COMMENT ‘用戶資料修改的時(shí)間’, user_review_status tinyint NOT NULL COMMENT ‘用戶資料審核狀態(tài)乌妒,1為通過汹想,2為審核中,3為未通過撤蚊,4為還未提交審核’, PRIMARY KEY (id), UNIQUE KEY idx_user_id (user_id), KEY idx_username(username), KEY idx_create_time(create_time,user_review_status)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='網(wǎng)站用戶基本信息';</pre>

2.2 SQL編寫

2.2.1 DML語句

  1. 【強(qiáng)制】SELECT語句必須指定具體字段名稱古掏,禁止寫成*。因?yàn)?code>select *會(huì)將不該讀的數(shù)據(jù)也從MySQL里讀出來侦啸,造成網(wǎng)卡壓力槽唾。且表字段一旦更新,但model層沒有來得及更新的話光涂,系統(tǒng)會(huì)報(bào)錯(cuò)庞萍。

  2. 【強(qiáng)制】insert語句指定具體字段名稱,不要寫成insert into t1 values(…)忘闻,道理同上挂绰。

  3. 【建議】insert into…values(XX),(XX),(XX)…。這里XX的值不要超過5000個(gè)服赎。值過多雖然上線很很快,但會(huì)引起主從同步延遲交播。

  4. 【建議】SELECT語句不要使用UNION重虑,推薦使用UNION ALL,并且UNION子句個(gè)數(shù)限制在5個(gè)以內(nèi)秦士。因?yàn)?code>union all不需要去重缺厉,節(jié)省數(shù)據(jù)庫資源,提高性能隧土。

  5. 【建議】in值列表限制在500以內(nèi)提针。例如select… where userid in(….500個(gè)以內(nèi)…),這么做是為了減少底層掃描曹傀,減輕數(shù)據(jù)庫壓力從而加速查詢辐脖。

  6. 【建議】事務(wù)里批量更新數(shù)據(jù)需要控制數(shù)量,進(jìn)行必要的sleep皆愉,做到少量多次嗜价。

  7. 【強(qiáng)制】事務(wù)涉及的表必須全部是innodb表幕庐。否則一旦失敗不會(huì)全部回滾异剥,且易造成主從庫同步終端冤寿。

  8. 【強(qiáng)制】寫入和事務(wù)發(fā)往主庫,只讀SQL發(fā)往從庫潮模。

  9. 【強(qiáng)制】除靜態(tài)表或小表(100行以內(nèi))擎厢,DML語句必須有where條件动遭,且使用索引查找厘惦。

  10. 【強(qiáng)制】生產(chǎn)環(huán)境禁止使用hint宵蕉,如sql_no_cache节榜,force indexignore key稼稿,straight join等讳窟。因?yàn)?code>hint是用來強(qiáng)制SQL按照某個(gè)執(zhí)行計(jì)劃來執(zhí)行丽啡,但隨著數(shù)據(jù)量變化我們無法保證自己當(dāng)初的預(yù)判是正確的,因此我們要相信MySQL優(yōu)化器倚评!

  11. 【強(qiáng)制】where條件里等號(hào)左右字段類型必須一致天梧,否則無法利用索引。

  12. 【建議】SELECT|UPDATE|DELETE|REPLACE要有WHERE子句后豫,且WHERE子句的條件必需使用索引查找挫酿。

  13. 【強(qiáng)制】生產(chǎn)數(shù)據(jù)庫中強(qiáng)烈不推薦大表上發(fā)生全表掃描早龟,但對(duì)于100行以下的靜態(tài)表可以全表掃描葱弟。查詢數(shù)據(jù)量不要超過表行數(shù)的25%,否則不會(huì)利用索引硅卢。

  14. 【強(qiáng)制】WHERE 子句中禁止只使用全模糊的LIKE條件進(jìn)行查找将塑,必須有其他等值或范圍查詢條件抬旺,否則無法利用索引。

  15. 【建議】索引列不要使用函數(shù)或表達(dá)式,否則無法利用索引汉柒。如where length(name)='Admin'where user_id+2=10023误褪。

  16. 【建議】減少使用or語句碾褂,可將or語句優(yōu)化為union兽间,然后在各個(gè)where條件上建立索引正塌。如where a=1 or b=2優(yōu)化為where a=1… union …where b=2, key(a),key(b)嘀略。

  17. 【建議】分頁查詢,當(dāng)limit起點(diǎn)較高時(shí)乓诽,可先用過濾條件進(jìn)行過濾。如select a,b,c from t1 limit 10000,20;優(yōu)化為: select a,b,c from t1 where id>10000 limit 20;鸠天。

2.2.2 多表連接

  1. 【強(qiáng)制】禁止跨db的join語句。因?yàn)檫@樣可以減少模塊間耦合饥瓷,為數(shù)據(jù)庫拆分奠定堅(jiān)實(shí)基礎(chǔ)呢铆。

  2. 【強(qiáng)制】禁止在業(yè)務(wù)的更新類SQL語句中使用join棺克,比如update t1 join t2…吼砂。

  3. 【建議】不建議使用子查詢逆航,建議將子查詢SQL拆開結(jié)合程序多次查詢,或使用join來代替子查詢渔肩。

  4. 【建議】線上環(huán)境因俐,多表join不要超過3個(gè)表。

  5. 【建議】多表連接查詢推薦使用別名周偎,且SELECT列表中要用別名引用字段抹剩,數(shù)據(jù)庫.表格式,如select a from db1.table1 alias1 where …蓉坎。

  6. 【建議】在多表join中澳眷,盡量選取結(jié)果集較小的表作為驅(qū)動(dòng)表,來join其他表蛉艾。

2.2.3 事務(wù)

  1. 【建議】事務(wù)中INSERT|UPDATE|DELETE|REPLACE語句操作的行數(shù)控制在2000以內(nèi)钳踊,以及WHERE子句中IN列表的傳參個(gè)數(shù)控制在500以內(nèi)勿侯。

  2. 【建議】批量操作數(shù)據(jù)時(shí)助琐,需要控制事務(wù)處理間隔時(shí)間蛆橡,進(jìn)行必要的sleep葱轩,一般建議值5-10秒复亏。

  3. 【建議】對(duì)于有auto_increment屬性字段的表的插入操作,并發(fā)需要控制在200以內(nèi)笤成。

  4. 【強(qiáng)制】程序設(shè)計(jì)必須考慮“數(shù)據(jù)庫事務(wù)隔離級(jí)別”帶來的影響培遵,包括臟讀、不可重復(fù)讀和幻讀。線上建議事務(wù)隔離級(jí)別為repeatable-read

  5. 【建議】事務(wù)里包含SQL不超過5個(gè)(支付業(yè)務(wù)除外)蛉迹。因?yàn)檫^長的事務(wù)會(huì)導(dǎo)致鎖數(shù)據(jù)較久,MySQL內(nèi)部緩存宅倒、連接消耗過多等雪崩問題疗绣。

  6. 【建議】事務(wù)里更新語句盡量基于主鍵或unique key塔逃,如update … where id=XX; 否則會(huì)產(chǎn)生間隙鎖立轧,內(nèi)部擴(kuò)大鎖定范圍格粪,導(dǎo)致系統(tǒng)性能下降,產(chǎn)生死鎖肺孵。

  7. 【建議】盡量把一些典型外部調(diào)用移出事務(wù)匀借,如調(diào)用webservice,訪問文件存儲(chǔ)等平窘,從而避免事務(wù)過長吓肋。

  8. 【建議】對(duì)于MySQL主從延遲嚴(yán)格敏感的select語句,請(qǐng)開啟事務(wù)強(qiáng)制訪問主庫瑰艘。

2.2.4 排序和分組

  1. 【建議】減少使用order by是鬼,和業(yè)務(wù)溝通能不排序就不排序紫新,或?qū)⑴判蚍诺匠绦蚨巳プ觥?code>order by、group by囤耳、distinct這些語句較為耗費(fèi)CPU,數(shù)據(jù)庫的CPU資源是極其寶貴的偶芍。

  2. 【建議】order by充择、group by匪蟀、distinct這些SQL盡量利用索引直接檢索出排序好的數(shù)據(jù)。如where a=1 order by可以利用key(a,b)材彪。

  3. 【建議】包含了order by观挎、group by琴儿、distinct這些查詢的語句,where條件過濾出來的結(jié)果集請(qǐng)保持在1000行以內(nèi)造成,否則SQL會(huì)很慢普气。

2.2.5 線上禁止使用的SQL語句

  1. 【高危】禁用update|delete t1 … where a=XX limit XX; 這種帶limit的更新語句夷磕。因?yàn)闀?huì)導(dǎo)致主從不一致仔沿,導(dǎo)致數(shù)據(jù)錯(cuò)亂。建議加上order by PK绵跷。

  2. 【高纬筛#】禁止使用關(guān)聯(lián)子查詢,如update t1 set … where name in(select name from user where…);效率極其低下净当。

  3. 【強(qiáng)制】禁用procedure蕴潦、function、trigger忽冻、views此疹、event、外鍵約束湖笨。因?yàn)樗麄兿臄?shù)據(jù)庫資源衍菱,降低數(shù)據(jù)庫實(shí)例可擴(kuò)展性肩豁。推薦都在程序端實(shí)現(xiàn)辫呻。

  4. 【強(qiáng)制】禁用insert into …on duplicate key update…在高并發(fā)環(huán)境下琼锋,會(huì)造成主從不一致缕坎。

  5. 【強(qiáng)制】禁止聯(lián)表更新語句,如update t1,t2 where t1.id=t2.id…谜叹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末荷腊,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子猜年,更是在濱河造成了極大的恐慌疾忍,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杨幼,死亡現(xiàn)場離奇詭異擒抛,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)歹撒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門暖夭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撵孤,“玉大人,你說我怎么就攤上這事裕菠”兆ǎ” “怎么了旧烧?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵掘剪,是天一觀的道長奈虾。 經(jīng)常有香客問我,道長匾鸥,這世上最難降的妖魔是什么浪册? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任村象,我火速辦了婚禮,結(jié)果婚禮上躁劣,老公的妹妹穿的比我還像新娘库菲。我一直安慰自己,他們只是感情好鳖擒,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布烫止。 她就那樣靜靜地躺著馆蠕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪互躬。 梳的紋絲不亂的頭發(fā)上吼渡,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音坎背,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛耿戚,可吹牛的內(nèi)容都是我干的阿趁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼皂股,長吁一口氣:“原來是場噩夢啊……” “哼命黔!你這毒婦竟也來了悍募?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤洋魂,失蹤者是張志新(化名)和其女友劉穎喜鼓,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豁翎,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谨垃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年硼控,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了牢撼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡纷责,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出挺勿,到底是詐尸還是另有隱情喂柒,我是刑警寧澤,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布蚊丐,位于F島的核電站艳吠,受9級(jí)特大地震影響昭娩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜栏渺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一迈嘹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧融痛,春花似錦神僵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽胁赢。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間徒河,已是汗流浹背送漠。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國打工闽寡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓淆院,卻偏偏與公主長得像句惯,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子拷淘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354