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

http://www.reibang.com/p/fd8533b60a74

https://zhuanlan.zhihu.com/p/131467045?from_voters_page=true
MySQL 數(shù)據(jù)庫設(shè)計規(guī)范(存檔)

信仰與初衷關(guān)注

2020.05.28 17:04:04字?jǐn)?shù) 5,761閱讀 4

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

目錄

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

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

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

2.1.1 通用命名約定

2.1.2 庫

2.1.3 表

2.1.4 字段名

2.1.5 字段數(shù)據(jù)類型優(yōu)化

2.1.6 索引設(shè)計

2.1.7 分庫分表丽旅、分區(qū)表

2.1.8 字符集

2.1.9 程序?qū)?DAO 設(shè)計建議

2.1.10 一個規(guī)范的建表語句示例

2.2 SQL 編寫

2.2.1 DML 語句

2.2.2 多表連接

2.2.3 事務(wù)

2.2.4 排序和分組

2.2.5 線上禁止使用的 SQL 語句

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

MySQL 數(shù)據(jù)庫與 Oracle榄笙、 SQL Server 等數(shù)據(jù)庫相比办斑,有其內(nèi)核上的優(yōu)勢與劣勢。我們在使用 MySQL 數(shù)據(jù)庫的時候需要遵循一定規(guī)范,揚長避短蠕蚜。本規(guī)范旨在幫助或指導(dǎo) RD悔橄、QA、OP 等技術(shù)人員做出適合線上業(yè)務(wù)的數(shù)據(jù)庫設(shè)計挣柬。在數(shù)據(jù)庫變更和處理流程邪蛔、數(shù)據(jù)庫表設(shè)計扎狱、SQL 編寫等方面予以規(guī)范淤击,從而為公司業(yè)務(wù)系統(tǒng)穩(wěn)定、健康地運行提供保障汞贸。

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

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

以下所有規(guī)范會按照【高斡』】耳贬、【強制】、【建議】三個級別進(jìn)行標(biāo)注顷蟆,遵守優(yōu)先級從高到低帐偎。

對于不滿足【高位滓伲】和【強制】兩個級別的設(shè)計,DBA 會強制打回要求修改漫贞。

2.1.1 一般命名規(guī)則

【強制】使用小寫迅脐,有助于提高打字速度,避免因大小寫敏感而導(dǎo)致的錯誤豌骏。

【強制】沒有空格窃躲,使用下劃線代替钦睡。

【強制】名稱中沒有數(shù)字赎婚,只有英文字母。

【強制】有效的可理解的名稱纬凤。

【強制】名稱應(yīng)該是自我解釋的撩嚼。

【強制】名稱不應(yīng)超過 32 個字符完丽。

【強制】避免使用前綴逻族。

2.1.2 庫

【強制】遵守以上全部一般命名規(guī)則。

【強制】使用單數(shù)薄辅。

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

【強制】一般分庫名稱命名格式是庫通配名_編號搏嗡,編號從 0 開始遞增拉一,比如?northwind_001蔚润,以時間進(jìn)行分庫的名稱格式是庫通配名_時間良蛮。

【強制】創(chuàng)建數(shù)據(jù)庫時必須顯式指定字符集决瞳,并且字符集只能是 utf8 或者 utf8mb4左权。創(chuàng)建數(shù)據(jù)庫 SQL 舉例:

createdatabasedb_namedefaultcharactersetutf8;

2.1.3 表

【強制】遵守以上全部一般命名規(guī)則赏迟。

【強制】使用單數(shù)锌杀。

【強制】相關(guān)模塊的表名與表名之間盡量體現(xiàn) join 的關(guān)系,如?user?表和?user_login?表量没。

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

【強制】創(chuàng)建表時必須顯式指定表存儲引擎類型猾担,如無特殊需求绑嘹,一律為 InnoDB。當(dāng)需要使用除 InnoDB/MyISAM/Memory 以外的存儲引擎時姨丈,必須通過 DBA 審核才能在生產(chǎn)環(huán)境中使用构挤。因為 InnoDB 表支持事務(wù)惕鼓、行鎖、宕機恢復(fù)一膨、MVCC 等關(guān)系型數(shù)據(jù)庫重要特性洒沦,為業(yè)界使用最多的 MySQL 存儲引擎申眼。而這是其它大多數(shù)存儲引擎不具備的括尸,因此首推 InnoDB。

【強制】建表必須有 comment屁柏。

【強制】關(guān)于主鍵:(1) 命名為?id有送,類型為 int 或 bigint雀摘,且為?auto_increment届宠;(2) 標(biāo)識表里每一行主體的字段不要設(shè)為主鍵,建議設(shè)為其它字段如?user_id伤塌,order_id等每聪,并建立?unique key?索引齿风。因為如果設(shè)為主鍵且主鍵值為隨機插入救斑,則會導(dǎo)致 InnoDB 內(nèi)部 page 分裂和大量隨機 I/O,性能下降穷娱。

【建議】核心表(如用戶表泵额,金錢相關(guān)的表)必須有行數(shù)據(jù)的創(chuàng)建時間字段?create_time?和最后更新時間字段?update_time嫁盲,便于排查問題。

【建議】表中所有字段必須都是?NOT NULL?屬性缸托,業(yè)務(wù)可以根據(jù)需要定義?DEFAULT?值嗦董。因為使用?NULL?值會存在每一行都會占用額外存儲空間瘦黑、數(shù)據(jù)遷移容易出錯幸斥、聚合函數(shù)計算結(jié)果偏差等問題甲葬。

【建議】建議對表里的?blob懈贺、text?等大字段梭灿,垂直拆分到其它表里,僅在需要讀這些對象的時候才去 select配乱。

【建議】反范式設(shè)計:把經(jīng)常需要 join 查詢的字段搬泥,在其它表里冗余一份忿檩。如?username?屬性在?user_account爆阶,user_login_log?等表里冗余一份,減少 join 查詢芭碍。

【強制】中間表用于保留中間結(jié)果集窖壕,名稱必須以?tmp_?開頭杉女。備份表用于備份或抓取源表快照熏挎,名稱必須以?bak_?開頭坎拐。中間表和備份表定期清理。

【強制】對于超過 100W 行的大表進(jìn)行?alter table都伪,必須經(jīng)過 DBA 審核陨晶,并在業(yè)務(wù)低峰期執(zhí)行先誉。因為?alter table?會產(chǎn)生表鎖的烁,期間阻塞對于該表的所有寫入撮躁,對于業(yè)務(wù)可能會產(chǎn)生極大影響把曼。

2.1.4 字段

【強制】遵守以上全部一般命名規(guī)則。

【建議】盡可能選擇短的或一兩個單詞注盈。

【強制】避免使用保留字作為字段名稱:order老客,date胧砰,name?是數(shù)據(jù)庫的保留字,避免使用它偿乖√靶剑可以為這些名稱添加前綴使其易于理解画切,如?user_name囱怕,signup_date?等。

【強制】避免使用與表名相同的字段名娃弓,這會在編寫查詢時造成混淆庞萍。

【強制】在數(shù)據(jù)庫模式上定義外鍵。

【強制】避免使用縮寫或基于首字母縮寫詞的名稱忘闻。

【強制】外鍵列必須具有表名及其主鍵,例如:blog_id?表示來自表博客的外鍵 id恋博。

2.1.5 字段數(shù)據(jù)類型優(yōu)化

【建議】表中的自增列(auto_increment?屬性)齐佳,推薦使用?bigint?類型。因為無符號?int?存儲范圍為?0~4,294,967,295(不到 43 億)债沮,溢出后會導(dǎo)致報錯。

【建議】業(yè)務(wù)中選擇性很少的狀態(tài)?status疫衩、類型?type?等字段推薦使用?tinytint?或者?smallint?類型節(jié)省存儲空間硅蹦。

【建議】業(yè)務(wù)中 IP 地址字段推薦使用?int?類型,不推薦用?char(15)闷煤。因為?int?只占 4 字節(jié)童芹,可以用如下函數(shù)相互轉(zhuǎn)換,而?char(15)?占用至少 15 字節(jié)鲤拿。

SQL:

selectinet_aton('192.168.2.12');selectinet_ntoa(3232236044);

PHP:

ip2long('192.168.2.12');long2ip(3530427185);

Java:

publicstaticlongipToLong(Stringaddr){String[]addrArray=addr.split("\\.");longnum=0;for(inti=0;i<addrArray.length;i++){intpower=3-i;num+=((Integer.parseInt(addrArray[i])%256*Math.pow(256,power)));}returnnum;}publicstaticStringlongToIp(longi){return((i>>24)&0xFF)+"."+((i>>16)&0xFF)+"."+((i>>8)&0xFF)+"."+(i&0xFF);}

【建議】不推薦使用?enum假褪,set。 因為它們浪費空間近顷,且枚舉值寫死了生音,變更不方便宁否。推薦使用?tinyint?或?smallint。

【建議】不推薦使用?blob缀遍,text?等類型慕匠。它們都比較浪費硬盤和內(nèi)存空間。在加載表數(shù)據(jù)時域醇,會讀取大字段到內(nèi)存里從而浪費內(nèi)存空間台谊,影響系統(tǒng)性能。建議和 PM歹苦、RD 溝通青伤,是否真的需要這么大字段。InnoDB 中當(dāng)一行記錄超過 8098 字節(jié)時殴瘦,會將該記錄中選取最長的一個字段將其 768 字節(jié)放在原始 page 里狠角,該字段余下內(nèi)容放在?overflow-page?里。不幸的是在?compact?行格式下蚪腋,原始?page?和?overflow-page?都會加載丰歌。

【建議】存儲金錢的字段,建議用?int?以分為單位存儲屉凯,最大數(shù)值約 4290 萬立帖,程序端乘以 100 和除以 100 進(jìn)行存取。因為?int?占用 4 字節(jié)悠砚,而?double?占用8字節(jié)晓勇,空間浪費。

【建議】文本數(shù)據(jù)盡量用?varchar?存儲灌旧。因為?varchar?是變長存儲绑咱,比?char?更省空間。MySQL server 層規(guī)定一行所有文本最多存 65535 字節(jié)枢泰,因此在 utf8 字符集下最多存 21844 個字符描融,超過會自動轉(zhuǎn)換為?mediumtext?字段。而?text?在 utf8 字符集下最多存 21844 個字符衡蚂,mediumtext?最多存 2^24/3 個字符窿克,longtext?最多存 2^32 個字符。一般建議用?varchar?類型毛甲,字符數(shù)不要超過 2700年叮。

【建議】時間類型盡量選取?timestamp。因為?datetime?占用 8 字節(jié)玻募,timestamp?僅占用4字節(jié)谋右,但是范圍為?1970-01-01 00:00:01?到?2038-01-01 00:00:00。更為高階的方法补箍,選用?int?來存儲時間改执,使用 SQL 函數(shù)?unix_timestamp()?和?from_unixtime()?來進(jìn)行轉(zhuǎn)換啸蜜。

詳細(xì)存儲大小參考下圖:

類型(同義詞)存儲長度(BYTES)最小值(SIGNED/UNSIGNED)最大值(SIGNED/UNSIGNED)

整形數(shù)字

TINYINT1-128/0127/255

SMALLINT2-32,768/032767/65,535

MEDIUMINT3-8,388,608/08388607/16,777,215/

INT(INTEGER)4-2,14,7483,648/02147483647/4,294,967,295/

BIGINT8-2^63/0263-1/264-1

小數(shù)支持

FLOAT[(M[,D])]4 or 8-

DOUBLE[(M[,D])]

(REAL, DOUBLE PRECISION)

8-

時間類型

DATETIME81001-01-01 00:00:009999-12-31 23:59:59

DATE31001-01-019999-12-31

TIME300:00:0023:59:59

YEAR110019999

TIMESTAMP41970-01-01 00:00:00

2.1.6 索引設(shè)計

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

【建議】主鍵的名稱以?pk_?開頭衬横,唯一鍵以?uk_?開頭,普通索引以?ix_?開頭终蒂,一律使用小寫格式蜂林,以表名/字段的名稱或縮寫作為后綴。

【強制】InnoDB 和 MyISAM 存儲引擎表拇泣,索引類型必須為?BTREE噪叙;MEMORY 表可以根據(jù)需要選擇?HASH?或者?BTREE?類型索引。

【強制】單個索引中每個索引記錄的長度不能超過 64KB霉翔。

【建議】單個表上的索引個數(shù)不能超過 7 個睁蕾。

【建議】在建立索引時,多考慮建立聯(lián)合索引债朵,并把區(qū)分度最高的字段放在最前面子眶。如列?user_id?的區(qū)分度可由?select count(distinct user_id)?計算出來。

【建議】在多表 join 的 SQL 里序芦,保證被驅(qū)動表的連接列上有索引臭杰,這樣 join 執(zhí)行效率最高。

【建議】建表或加索引時谚中,保證表里互相不存在冗余索引渴杆。對于 MySQL 來說,如果表里已經(jīng)存在?key(a, b)宪塔,則?key(a)?為冗余索引将塑,需要刪除。

【建議】如果選擇性超過 20%蝌麸,那么全表掃描比使用索引性能更優(yōu),即沒有設(shè)置索引的必要艾疟。

2.1.7 分庫分表来吩、分區(qū)表

【強制】分區(qū)表的分區(qū)字段(partition-key)必須有索引,或者是組合索引的首列蔽莱。

【強制】單個分區(qū)表中的分區(qū)(包括子分區(qū))個數(shù)不能超過 1024弟疆。

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

【強制】訪問分區(qū)表的 SQL 必須包含分區(qū)鍵怠苔。

【建議】單個分區(qū)文件不超過 2G,總大小不超過 50G仪糖。建議總分區(qū)數(shù)不超過 20 個柑司。

【強制】對于分區(qū)表執(zhí)行?alter table?操作迫肖,必須在業(yè)務(wù)低峰期執(zhí)行。

【強制】采用分庫策略的攒驰,庫的數(shù)量不能超過 1024蟆湖。

【強制】采用分表策略的,表的數(shù)量不能超過 4096玻粪。

【建議】單個分表不超過 500W 行隅津,ibd 文件大小不超過 2G,這樣才能讓數(shù)據(jù)分布式變得性能更佳劲室。

【建議】水平分表盡量用取模方式伦仍,日志、報表類數(shù)據(jù)建議采用日期進(jìn)行分表很洋。

2.1.8 字符集

【強制】數(shù)據(jù)庫本身庫充蓝、表、列所有字符集必須保持一致蹲缠,為?utf8?或?utf8mb4棺克。

【強制】前端程序字符集或者環(huán)境變量中的字符集,與數(shù)據(jù)庫线定、表的字符集必須一致娜谊,統(tǒng)一為?utf8。

2.1.9 程序?qū)?DAO 設(shè)計建議

【建議】新的代碼不要用 model斤讥,推薦使用手動拼 SQL + 綁定變量傳入?yún)?shù)的方式纱皆。因為 model 雖然可以使用面向?qū)ο蟮姆绞讲僮?db,但是其使用不當(dāng)很容易造成生成的 SQL 非常復(fù)雜芭商,且 model 層自己做的強制類型轉(zhuǎn)換性能較差派草,最終導(dǎo)致數(shù)據(jù)庫性能下降。

【建議】前端程序連接 MySQL 或者 Redis铛楣,必須要有連接超時和失敗重連機制近迁,且失敗重試必須有間隔時間。

【建議】前端程序報錯里盡量能夠提示 MySQL 或 Redis 原生態(tài)的報錯信息簸州,便于排查錯誤鉴竭。

【建議】對于有連接池的前端程序,必須根據(jù)業(yè)務(wù)需要配置初始岸浑、最小搏存、最大連接數(shù),超時時間以及連接回收機制矢洲,否則會耗盡數(shù)據(jù)庫連接資源璧眠,造成線上事故。

【建議】對于?log?或?history?類型的表,隨時間增長容易越來越大责静,因此上線前 RD 或者 DBA 必須建立表數(shù)據(jù)清理或歸檔方案袁滥。

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

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

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

【建議】對于單表讀寫比大于 10:1 的數(shù)據(jù)行或單個列本谜,可以將熱點數(shù)據(jù)放在緩存里(如 Memcached 或 Redis)初家,加快訪問速度,降低 MySQL 壓力乌助。

2.1.10 一個規(guī)范的建表語句示例

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

createtableuser(`id`bigint(11)notnullauto_increment,`user_id`bigint(11)notnullcomment'用戶 ID',`username`varchar(45)notnullcomment'登錄名',`email`varchar(30)notnullcomment'郵箱',`nickname`varchar(45)notnullcomment'昵稱',`avatar`int(11)notnullcomment'頭像',`birthday`datenotnullcomment'生日',`gender`tinyint(4)default'0'comment'性別',`intro`varchar(150)defaultnullcomment'簡介',`resume_url`varchar(300)notnullcomment'簡歷存放地址',`register_ip`intnotnullcomment'用戶注冊時的源 IP',`review_status`tinyintnotnullcomment'審核狀態(tài)溜在,1-通過,2-審核中他托,3-未通過掖肋,4-尚未提交審核',`create_time`timestampnotnullcomment'記錄創(chuàng)建的時間',`update_time`timestampnotnullcomment'資料修改的時間',primarykey(`id`),uniquekey`idx_user_id`(`user_id`),key`idx_username`(`username`),key`idx_create_time`(`create_time`,`review_status`))engine=InnoDBdefaultcharset=utf8comment='用戶基本信息';

2.2 SQL 編寫

2.2.1 DML 語句

【強制】select 語句必須指定具體字段名稱,禁止寫成?*赏参。因為?select *?會將不該讀的數(shù)據(jù)也從 MySQL 里讀出來志笼,造成網(wǎng)卡壓力。

【強制】insert 語句指定具體字段名稱把篓,不要寫成?insert into t1 values(…)纫溃,道理同上。

【建議】insert into … values(xx),(xx),(xx)…韧掩,這里 xx 的值不要超過 5000 個紊浩。值過多雖然上線很快,但會引起主從同步延遲疗锐。

【建議】select 語句不要使用?union坊谁,推薦使用?union all,并且?union?子句個數(shù)限制在 5 個以內(nèi)窒悔。因為?union all?不需要去重,節(jié)省數(shù)據(jù)庫資源敌买,提高性能简珠。

【建議】in 值列表限制在 500 以內(nèi)。例如?select … where user_id in(…500 個以內(nèi)…)聋庵,這么做是為了減少底層掃描膘融,減輕數(shù)據(jù)庫壓力從而加速查詢。

【建議】事務(wù)里批量更新數(shù)據(jù)需要控制數(shù)量祭玉,進(jìn)行必要的 sleep氧映,做到少量多次。

【強制】事務(wù)涉及的表必須全部是 InnoDB 表脱货。否則一旦失敗不會全部回滾岛都,且易造成主從庫同步終端。

【強制】寫入和事務(wù)發(fā)往主庫振峻,只讀 SQL 發(fā)往從庫臼疫。

【強制】除靜態(tài)表或小表(100 行以內(nèi)),dml 語句必須有 where 條件扣孟,且使用索引查找烫堤。

【強制】生產(chǎn)環(huán)境禁止使用?hint,如?sql_no_cache凤价,force index鸽斟,ignore key,straight join?等利诺。因為?hint?是用來強制 sql 按照某個執(zhí)行計劃來執(zhí)行富蓄,但隨著數(shù)據(jù)量變化我們無法保證自己當(dāng)初的預(yù)判是正確的,因此我們要相信 MySQL 優(yōu)化器立轧。

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

【建議】select|update|delete|replace?要有 where 子句氛改,且 where 子句的條件必需使用索引查找帐萎。

【強制】生產(chǎn)數(shù)據(jù)庫中強烈不推薦大表上發(fā)生全表掃描,但對于 100 行以下的靜態(tài)表可以全表掃描胜卤。查詢數(shù)據(jù)量不要超過表行數(shù)的 25%疆导,否則不會利用索引。

【強制】where 子句中禁止只使用全模糊的 like 條件進(jìn)行查找葛躏,必須有其它等值或范圍查詢條件澈段,否則無法利用索引。

【建議】索引列不要使用函數(shù)或表達(dá)式舰攒,否則無法利用索引败富。如?where length(name) = 'admin'?或?where user_id + 2 = 10023。

【建議】減少使用 or 語句摩窃,可將 or 語句優(yōu)化為 union兽叮,然后在各個 where 條件上建立索引芬骄。如?where a = 1 or b = 2?優(yōu)化為?where a = 1 … union … where b = 2, key(a), key(b)。

【建議】分頁查詢鹦聪,當(dāng)?limit?起點較高時账阻,可先用過濾條件進(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 多表連接

【強制】禁止跨 DB 的 join 語句淘太。因為這樣可以減少模塊間耦合,為數(shù)據(jù)庫拆分奠定堅實基礎(chǔ)规丽。

【強制】禁止在業(yè)務(wù)的更新類 SQL 語句中使用 join蒲牧,比如?update t1 join t2 …。

【建議】不建議使用子查詢嘁捷,建議將子查詢 SQL 拆開結(jié)合程序多次查詢造成,或使用 join 來代替子查詢。

【建議】線上環(huán)境雄嚣,多表 join 不要超過 3 個表晒屎。

【建議】多表連接查詢推薦使用別名,且 select 列表中要用別名引用字段缓升,數(shù)據(jù)庫.表格式鼓鲁,如?select a from db1.table1 alias1 where …。

【建議】在多表 join 中港谊,盡量選取結(jié)果集較小的表作為驅(qū)動表骇吭,來 join 其它表。

2.2.3 事務(wù)

【建議】事務(wù)中?insert|update|delete|replace?語句操作的行數(shù)控制在 2000 以內(nèi)歧寺,以及 where 子句中 in 列表的傳參個數(shù)控制在 500 以內(nèi)燥狰。

【建議】批量操作數(shù)據(jù)時,需要控制事務(wù)處理間隔時間斜筐,進(jìn)行必要的 sleep龙致,一般建議值 5-10 秒。

【建議】對于有?auto_increment?屬性字段的表的插入操作顷链,并發(fā)需要控制在 200 以內(nèi)目代。

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

【建議】事務(wù)里包含 SQL 不超過 5 個(支付業(yè)務(wù)除外)煞抬。因為過長的事務(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)生死鎖蹦骑。

【建議】盡量把一些典型外部調(diào)用移出事務(wù)慈省,如調(diào)用 Web Service,訪問文件存儲等眠菇,從而避免事務(wù)過長边败。

【建議】對于 MySQL 主從延遲嚴(yán)格敏感的 select 語句,請開啟事務(wù)強制訪問主庫捎废。

2.2.4 排序和分組

【建議】減少使用?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?可以利用?key(a, b)。

【建議】包含了?order by续捂、group by垦垂、distinct?這些查詢的語句,where 條件過濾出來的結(jié)果集請保持在 1000 行以內(nèi)牙瓢,否則 SQL 會很慢劫拗。

2.2.5 線上禁止使用的 SQL 語句

【高危】禁用?update|delete t1 … where a = XX limit XX;?這種帶 limit 的更新語句一罩。因為會導(dǎo)致主從不一致杨幼,導(dǎo)致數(shù)據(jù)錯亂。建議加上?order by PK聂渊。

【高尾罟海】禁止使用關(guān)聯(lián)子查詢,如?update t1 set … where name in(select name from user where …);汉嗽,效率極其低下欲逃。

【強制】禁用 procedure、function饼暑、trigger稳析、views洗做、event、外鍵約束彰居。因為他們消耗數(shù)據(jù)庫資源诚纸,降低數(shù)據(jù)庫實例可擴展性。推薦都在程序端實現(xiàn)陈惰。

【強制】禁用?insert into … on duplicate key update …?在高并發(fā)環(huán)境下畦徘,會造成主從不一致。

【強制】禁止聯(lián)表更新語句抬闯,如?update t1, t2 where t1.id = t2.id …井辆。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市溶握,隨后出現(xiàn)的幾起案子杯缺,更是在濱河造成了極大的恐慌,老刑警劉巖睡榆,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萍肆,死亡現(xiàn)場離奇詭異,居然都是意外死亡胀屿,警方通過查閱死者的電腦和手機匾鸥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門碉纳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勿负,“玉大人,你說我怎么就攤上這事劳曹。” “怎么了铁孵?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵岖沛,是天一觀的道長。 經(jīng)常有香客問我婴削,道長廊镜,這世上最難降的妖魔是什么嗤朴? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任配椭,我火速辦了婚禮,結(jié)果婚禮上雹姊,老公的妹妹穿的比我還像新娘股缸。我一直安慰自己,他們只是感情好吱雏,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布乓序。 她就那樣靜靜地躺著,像睡著了一般坎背。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上寄雀,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天得滤,我揣著相機與錄音,去河邊找鬼盒犹。 笑死懂更,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的急膀。 我是一名探鬼主播沮协,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼卓嫂!你這毒婦竟也來了慷暂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤晨雳,失蹤者是張志新(化名)和其女友劉穎行瑞,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體餐禁,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡血久,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了帮非。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片氧吐。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖末盔,靈堂內(nèi)的尸體忽然破棺而出筑舅,到底是詐尸還是另有隱情,我是刑警寧澤陨舱,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布豁翎,位于F島的核電站,受9級特大地震影響隅忿,放射性物質(zhì)發(fā)生泄漏心剥。R本人自食惡果不足惜邦尊,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望优烧。 院中可真熱鬧蝉揍,春花似錦、人聲如沸畦娄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽熙卡。三九已至杖刷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間驳癌,已是汗流浹背滑燃。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留颓鲜,地道東北人表窘。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像甜滨,于是被迫代替她去往敵國和親乐严。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348