數(shù)據(jù)庫概念
鎖分類
鎖(按照鎖粒度分類)
表級鎖:每次操作鎖住整張表魁瞪。開銷小,加鎖快床佳;不會出現(xiàn)死鎖;鎖定粒度大榄审,發(fā)生鎖沖突的概率最高砌们,并發(fā)度最低
-
行級鎖:每次操作鎖住一行數(shù)據(jù)。開銷大搁进,加鎖慢浪感;會出現(xiàn)死鎖;鎖定粒度最小饼问,發(fā)生鎖沖突的概率最低影兽,并發(fā)度也最高
InnoDB
的行級鎖是針對索引加的鎖,不針對數(shù)據(jù)記錄
雖然行級索具有粒度小莱革、并發(fā)度高等特點(diǎn)峻堰,但是表級鎖有時候也是有其適用場景的:
- 事務(wù)更新大表中的大部分?jǐn)?shù)據(jù)直接使用表級鎖效率更高
- 事務(wù)比較復(fù)雜,使用行級索很可能引起死鎖導(dǎo)致回滾
鎖(按照讀寫分類)
表級鎖和行級鎖可以進(jìn)一步劃分為共享鎖(S)和排他鎖(X)
-
共享鎖(S),即讀鎖
其他用戶可以并發(fā)讀取數(shù)據(jù)盅视,但任何事務(wù)都不能獲取數(shù)據(jù)上的排他鎖捐名,直到已釋放所有共享鎖。
-
排他鎖(X),即寫鎖
若事務(wù)T對數(shù)據(jù)對象A加上X鎖闹击,則只允許T讀取和修改A桐筏,其它任何事務(wù)都不能再對A加任何類型的鎖,直到T釋放A上的鎖。
讀寫鎖有一定的缺憾梅忌,如遇到自己需要鎖定的資源已經(jīng)被一個排他鎖占有之后,則只能等待該鎖定釋放資源之后自己才能獲取鎖定資源并添加自己的鎖定除破,所以就有了意向鎖牧氮。
意向鎖解釋:
當(dāng)一個事務(wù)在需要獲取資源鎖定的時候,如果遇到自己需要的資源已經(jīng)被排他鎖占用的時候瑰枫,該事務(wù)可以需要鎖定行的表上面添加一個合適的意向鎖踱葛。如果自己需要一個共享鎖,那么就在表上面添加一個意向共享鎖光坝。而如果自己需要的是在某行(或者某些行)上面添加一個排他鎖的話尸诽,則先在表上面添加一個意向排他鎖。意向共享鎖可以同時并存多個盯另,但是意向排他鎖同時只能有一個存在性含。
InnoDB
另外的兩個表級鎖:
- 意向共享鎖(IS):表示事務(wù)準(zhǔn)備給數(shù)據(jù)行記入共享鎖,事務(wù)在一個數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖鸳惯。
- 意向排他鎖(IX):表示事務(wù)準(zhǔn)備給數(shù)據(jù)行加入排他鎖商蕴,事務(wù)在一個數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。
意向鎖是表級鎖芝发,表示的是一種意向绪商,僅僅表示事務(wù)正在讀或?qū)懩骋恍杏涗洠谡嬲有墟i時才會判斷是否沖突辅鲸。意向鎖是InnoDB
自動加的格郁,不需要用戶干預(yù)。
IX独悴,IS是表級鎖例书,不會和行級的X,S鎖發(fā)生沖突绵患,只會和表級的X雾叭,S發(fā)生沖突。
綜上落蝙,當(dāng)一個事務(wù)請求的鎖模式與當(dāng)前的鎖兼容织狐,InnoDB
就將請求的鎖授予該事務(wù);反之如果請求不兼容筏勒,則該事物就等待鎖釋放移迫。
頁級鎖
鎖定粒度介于行級鎖和表級鎖中間的一種鎖。
由于表級鎖速度快管行,但沖突多厨埋,行級沖突少,但速度慢捐顷。而頁級鎖進(jìn)行了折衷荡陷,一次鎖定相鄰的一組記錄雨效。開銷和加鎖時間界于表鎖和行鎖之間,會出現(xiàn)死鎖废赞。鎖定粒度界于表鎖和行鎖之間徽龟,并發(fā)度一般。
死鎖及其解決方法
由于InnoDB
的行級鎖是針對索引加的鎖唉地,不針對數(shù)據(jù)記錄据悔,因此即使訪問不同行的記錄,如果使用了相同的索引鍵仍然會出現(xiàn)鎖沖突耘沼,需要注意的是,在通過以下方式
SELECT ...LOCK IN SHARE MODE;
SELECT ...FOR UPDATE;
使用鎖的時候拷窜,如果表沒有定義任何索引巫橄,那么InnoDB
會創(chuàng)建一個隱藏的聚簇索引并使用這個索引來加記錄鎖台囱。
此外氏淑,不同于MyISAM
總是一次性獲得所需的全部鎖,InnoDB
的鎖是逐步獲得的骚烧,當(dāng)兩個事務(wù)都需要獲得對方持有的鎖浸赫,導(dǎo)致雙方都在等待,這就產(chǎn)生了死鎖赃绊。發(fā)生死鎖后既峡,InnoDB
一般都可以檢測到,并使一個事務(wù)釋放鎖回退碧查,另一個則可以獲取鎖完成事務(wù)运敢。當(dāng)然,我們可以自己事先做一些考慮:
- 通過表級鎖來減少死鎖產(chǎn)生的概率
- 多個程序盡量約定以相同的順序訪問表(這也是解決并發(fā)理論中哲學(xué)家就餐問題的一種思路)
- 同一個事務(wù)盡可能做到一次鎖定所需要的所有資源
鎖結(jié)論
間隙鎖主要還是用于防止幻讀的情況忠售,所以多個事務(wù)能夠同時獲取同一段間隙鎖本身并沒有問題传惠,間隙鎖能夠阻塞插入意向鎖也并沒有問題。
而插入意向鎖可以看成是一種特殊的間隙鎖稻扬,是用于在同一個間隙卦方,插入不同的數(shù)據(jù),不會互相阻塞泰佳。它比普通間隙鎖的數(shù)據(jù)一致性更低盼砍,但并發(fā)性能更好。
緩存查詢
實(shí)例針對Mysql說明:
my.cnf加入以下配置逝她,重啟Mysql開機(jī)查詢緩存
query_cache_type=1
query_cache_size=600000
Mysql執(zhí)行以下命令也可以開啟查詢緩存
set global query_cache_type=1;
set global query_cache_size=600000;
如上浇坐,開啟查詢緩存后在同樣的查詢條件以及數(shù)據(jù)情況下,會直接在緩存中返回結(jié)果黔宛。
上面所述的查詢條件包括查詢本身近刘、當(dāng)前要查詢的數(shù)據(jù)庫、客戶端協(xié)議版本號等一些可能影響結(jié)果的信息。因此任何兩個在任何字符上有不同的查詢都會導(dǎo)致緩存命不中觉渴。此外介劫,如果查詢中包含任何用戶自定義函數(shù)、存儲函數(shù)疆拘、用戶變量蜕猫、臨時表、Mysql
庫中的系統(tǒng)表哎迄,其查詢結(jié)果也不會被緩存。
當(dāng)緩存建立后隆圆,Mysql
的查詢緩存系統(tǒng)會跟蹤查詢中涉及的每張表漱挚,如果這些表(數(shù)據(jù)或結(jié)構(gòu))發(fā)生變化,那么和這張表相關(guān)的所有緩存數(shù)據(jù)都將失效渺氧。
緩存雖然能夠提升數(shù)據(jù)庫的查詢性能旨涝,但是緩存同時也帶來了額外的開銷,每次查詢后都要做一次緩存操作侣背,失效后還要銷毀,因此白华,開啟緩存查詢要謹(jǐn)慎,尤其對于寫密集的應(yīng)用來說更是如此贩耐。如果開啟弧腥,要注意合理控制緩存空間大小,一般來說其大小設(shè)置為幾十MB比較合適潮太。此外管搪,還可以通過sql_cache
和sql_no_cache
來控制某個查詢語句是否需要緩存:
select sql_no_cache count(*) from usr;
事務(wù)
事務(wù)特性
- 原子性: 事務(wù)是最小的執(zhí)行單位,不允許分割铡买。事務(wù)的原子性確保動作要么全部完成更鲁,要么完全不起作用;
- 一致性: 執(zhí)行事務(wù)前后奇钞,數(shù)據(jù)保持一致澡为;
- 隔離性: 并發(fā)訪問數(shù)據(jù)庫時,一個用戶的事物不被其他事物所干擾景埃,各并發(fā)事務(wù)之間數(shù)據(jù)庫是獨(dú)立的媒至;
- 持久性: 一個事務(wù)被提交之后。它對數(shù)據(jù)庫中數(shù)據(jù)的改變是持久的纠亚,即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響塘慕。
并發(fā)事務(wù)帶來的問題
臟讀(Dirty read): 當(dāng)一個事務(wù)正在訪問數(shù)據(jù)并且對數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交到數(shù)據(jù)庫中蒂胞,這時另外一個事務(wù)也訪問了這個數(shù)據(jù)图呢,然后使用了這個數(shù)據(jù)。因?yàn)檫@個數(shù)據(jù)是還沒有提交的數(shù)據(jù),那么另外一個事務(wù)讀到的這個數(shù)據(jù)是“臟數(shù)據(jù)”蛤织,依據(jù)“臟數(shù)據(jù)”所做的操作可能是不正確的赴叹。
-
丟失修改(Lost to modify): 指在一個事務(wù)讀取一個數(shù)據(jù)時,另外一個事務(wù)也訪問了該數(shù)據(jù)指蚜,那么在第一個事務(wù)中修改了這個數(shù)據(jù)后乞巧,第二個事務(wù)也修改了這個數(shù)據(jù)。這樣第一個事務(wù)內(nèi)的修改結(jié)果就被丟失摊鸡,因此稱為丟失修改绽媒。
例如:事務(wù)1讀取某表中的數(shù)據(jù)A=20,事務(wù)2也讀取A=20免猾,事務(wù)1修改A=A-1是辕,事務(wù)2也修改A=A-1,最終結(jié)果A=19猎提,事務(wù)1的修改被丟失获三。
不可重復(fù)讀(Unrepeatableread): 指在一個事務(wù)內(nèi)多次讀同一數(shù)據(jù)。在這個事務(wù)還沒有結(jié)束時锨苏,另一個事務(wù)也訪問該數(shù)據(jù)疙教。那么,在第一個事務(wù)中的兩次讀數(shù)據(jù)之間伞租,由于第二個事務(wù)的修改導(dǎo)致第一個事務(wù)兩次讀取的數(shù)據(jù)可能不太一樣贞谓。這就發(fā)生了在一個事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的情況,因此稱為不可重復(fù)讀肯夏。
幻讀(Phantom read): 幻讀與不可重復(fù)讀類似经宏。它發(fā)生在一個事務(wù)(T1)讀取了幾行數(shù)據(jù),接著另一個并發(fā)事務(wù)(T2)插入了一些數(shù)據(jù)時驯击。在隨后的查詢中烁兰,第一個事務(wù)(T1)就會發(fā)現(xiàn)多了一些原本不存在的記錄,就好像發(fā)生了幻覺一樣徊都,所以稱為幻讀沪斟。
? 其中,不可重復(fù)讀的重點(diǎn)是修改暇矫,幻讀的重點(diǎn)在于新增或者刪除.
事務(wù)隔離級別
-
READ_UNCOMMITTED
(未授權(quán)讀戎髦): 最低的隔離級別,允許讀取尚未提交的數(shù)據(jù)變更李根,可能會導(dǎo)致臟讀槽奕、幻讀或不可重復(fù)讀 -
READ_COMMITTED
(授權(quán)讀取): 允許讀取并發(fā)事務(wù)已經(jīng)提交的數(shù)據(jù)房轿,可以阻止臟讀粤攒,但是幻讀或不可重復(fù)讀仍有可能發(fā)生 -
REPEATABLE_READ
(可重復(fù)讀):對同一字段的多次讀取結(jié)果都是一致的所森,除非數(shù)據(jù)是被本身事務(wù)自己所修改,可以阻止臟讀和不可重復(fù)讀夯接,但幻讀仍有可能發(fā)生焕济。 -
SERIALIZABLE
(串行): 最高的隔離級別,完全服從ACID的隔離級別盔几。所有的事務(wù)依次逐個執(zhí)行晴弃,這樣事務(wù)之間就完全不可能產(chǎn)生干擾,也就是說逊拍,該級別可以防止臟讀上鞠、不可重復(fù)讀以及幻讀。但是這將嚴(yán)重影響程序的性能芯丧。通常情況下也不會用到該級別旗国。
MySql
架構(gòu)設(shè)計
存儲引擎
以5.5為例
特點(diǎn)比較
MyISAM
- 不支持行鎖(
MyISAM
只有表鎖),讀取時對需要讀到的所有表加鎖注整,寫入時則對表加排他鎖 - 不支持事務(wù)
- 不支持外鍵
- 不支持崩潰后的安全恢復(fù)
- 在表有讀取查詢的同時,支持往表中插入新紀(jì)錄
- 支持
BLOB
和TEXT
的前500個字符索引度硝,支持全文索引 - 支持延遲更新索引肿轨,極大地提升了寫入性能
- 對于不會進(jìn)行修改的表,支持壓縮表蕊程,極大地減少了磁盤空間的占用
InnoDB
- 支持表級鎖和行級鎖,有可能死鎖
- 支持事務(wù),其默認(rèn)的事務(wù)隔離級別是
REPEATABLE_READ
,Oracle
默認(rèn)采用的READ_COMMITTED
隔離級別 - 支持外鍵
- 支持崩潰后的安全恢復(fù)
- 不支持全文索引(
innodb
已經(jīng)在5.6.4
支持全文索引了)
InnoDB
行級鎖分類:
-
Record Lock
:對索引項(xiàng)加鎖椒袍,鎖定符合條件的行。其他事務(wù)不能修改和刪除加鎖項(xiàng)藻茂; -
Gap Lock
:對索引項(xiàng)之間的“間隙”加鎖驹暑,鎖定記錄的范圍(對第一條記錄前的間隙或最后一條將記錄后的間隙加鎖),不包含索引項(xiàng)本身辨赐。其他事務(wù)不能在鎖范圍內(nèi)插入數(shù)據(jù)优俘,這樣就防止了別的事務(wù)新增幻影行。 -
Next-key Lock
:鎖定索引項(xiàng)本身和索引范圍掀序。即Record Lock
和Gap Lock
的結(jié)合帆焕。可解決幻讀問題不恭。
事務(wù)隔離機(jī)制的實(shí)現(xiàn)基于鎖機(jī)制
和并發(fā)調(diào)度
叶雹。其中并發(fā)調(diào)度使用的是MVVC
(多版本并發(fā)控制),通過保存修改的舊版本信息來支持并發(fā)一致性讀和回滾等特性
綜上:MyISAM
更適合讀密集的表换吧,而InnoDB
更適合寫密集的的表折晦。在數(shù)據(jù)庫做主從分離的情況下,可以選擇MyISAM
作為主庫的存儲引擎沾瓦。
索引結(jié)構(gòu)
MyISAM
和InnoDB
都使用B+樹作為其索引結(jié)構(gòu)
但二者也是有區(qū)別的:
- 在
InnoDB
中满着,表數(shù)據(jù)文件是按B+樹
組織的索引結(jié)構(gòu)谦炒,這棵樹的葉節(jié)點(diǎn)data域保存了完整的數(shù)據(jù)記錄(這種索引叫聚集索引),而MyISAM
索引文件和數(shù)據(jù)文件是分離的(非聚集的)漓滔,索引文件僅保存數(shù)據(jù)記錄的地址,當(dāng)定位到具體的數(shù)據(jù)記錄地址后编饺,還需要一次IO才能找到具體的數(shù)據(jù)記錄 -
InnoDB
輔助索引data域存儲的是相應(yīng)記錄主鍵的值,即InnoDB
的所有輔助索引都引用主鍵作為其data域响驴,而MyISAM
輔助索引data域存儲的是相應(yīng)記錄的地址
綜上可知透且,InnoDB
在根據(jù)主索引查找數(shù)據(jù)時,直接找到key所在的節(jié)點(diǎn)即可取出數(shù)據(jù)文件豁鲤,在根據(jù)輔助索引查找數(shù)據(jù)時秽誊,首先需要在key所在的節(jié)點(diǎn)的數(shù)據(jù)文件中找到主鍵值,再通過主鍵走一遍主鍵索引才能找到對應(yīng)的數(shù)據(jù)文件(即輔助索引搜索需要檢索兩遍索引)琳骡。當(dāng)使用InnoDB
創(chuàng)建表時锅论,盡量指明主鍵,當(dāng)不包含主鍵時楣号,存儲引擎會生成默認(rèn)的主鍵索引最易,其長度為6B。除此之外炫狱,不建議使用過長的字段作為主鍵藻懒,因?yàn)檩o助索引是通過引用主索引找到其真正的數(shù)據(jù)文件的,過長的主索引會令輔助索引變得過大视译;也不建議用非單調(diào)的字段作為主鍵嬉荆,由于InnoDB
數(shù)據(jù)文件是一顆B+樹,非單調(diào)的主鍵會造成在插入新記錄時數(shù)據(jù)文件為了維持B+樹的特性而頻繁的分裂調(diào)整酷含,十分低效鄙早,建議使用自增值作為主鍵(這樣可使隨機(jī)insert變?yōu)轫樞騛ppend,不會產(chǎn)生頁分裂和碎片椅亚,提升寫性能)限番。
事務(wù)處理機(jī)制
InnoDB
事務(wù)日志
InnoDB 使用undo
,redo log
來保證事務(wù)原子性、一致性及持久性什往,同時采用預(yù)寫日志方式將隨機(jī)寫入變成順序追加寫入扳缕,提升事務(wù)性能。
-
undo log:記錄事務(wù)變更前的狀態(tài)别威。操作數(shù)據(jù)之前躯舔,先將數(shù)據(jù)備份到
undo log
,然后進(jìn)行數(shù)據(jù)修改省古,如果出現(xiàn)錯誤或用戶執(zhí)行了rollback
語句粥庄,則系統(tǒng)就可以利用undo log
中的歷史版本恢復(fù)到事務(wù)開始之前的狀態(tài)。 -
redo log:記錄事務(wù)將要變更后的狀態(tài)豺妓。事務(wù)提交時惜互,只要將
redo log
持久化即可布讹,數(shù)據(jù)可在內(nèi)存中變更。當(dāng)系統(tǒng)崩潰時训堆,雖然數(shù)據(jù)沒有落盤描验,但是redo log
已持久化,系統(tǒng)可以根據(jù)redo log
的內(nèi)容坑鱼,將所有數(shù)據(jù)恢復(fù)到最新的狀態(tài)膘流。 -
checkpoint:隨著時間的積累,
redo log
會變的很大很大鲁沥。如果每次都從第一條記錄開始恢復(fù)呼股,恢復(fù)的過程就會很慢。為了減少恢復(fù)的時間画恰,就引入了checkpoint
機(jī)制彭谁。定期將databuffer
的內(nèi)容刷新到磁盤datafile
內(nèi),然后清除checkpoint
之前的redo log
允扇。 -
自動恢復(fù):InnoDB通過加載最新快照缠局,然后重放最近的
checkpoint
點(diǎn)之后所有redo log
事務(wù)(包括未提交和回滾了的),再通過undo log
回滾那些未提交的事務(wù)考润,來完成數(shù)據(jù)恢復(fù)甩鳄。需要注意的地方是,undo log
其實(shí)也是行數(shù)據(jù)额划,對其寫操作也會記錄到redo log
內(nèi),即undo log
也是通過redo log
來保證持久化的档泽。
下圖為事務(wù)寫操作執(zhí)行的大致過程俊戳,整個過程中只有一次刷盤操作,即事務(wù)提交時的redo log
的寫盤馆匿。
其實(shí)寫盤并不一定會立馬持久化到磁盤抑胎,要看數(shù)據(jù)庫配置,默認(rèn)情況下Innodb_flush_log_at_trx_commit=1
渐北,即一次redo log
寫盤操作會立即寫到磁盤中阿逃,是最保險的方案。
InnoDB
中多個事務(wù)共享一個redo log buffer
赃蛛, 寫盤時恃锉,會將當(dāng)前buffer
中的多個事務(wù)日志持久化,而不管事務(wù)有沒有commit
呕臂,而且并不是只有事務(wù)commit
才會觸發(fā)redo log
寫盤破托,其它操作也會觸發(fā)redo log
寫盤操作如:
-
redo log buffer
空間不足 - 觸發(fā)
checkpoint
- 實(shí)例
shutdown
-
binlog
切換時
MVCC
MVCC (Multi-Version Concurrency Control)
多版本并發(fā)控制協(xié)議,將讀操作分成兩類:快照讀 與當(dāng)前讀 歧蒋。讀取的是記錄的最新版本土砂,會對返回的記錄加上鎖州既,確保其他事務(wù)不能并發(fā)修改。
-
快照讀:簡單的查詢操作萝映,屬于快照讀吴叶,不加鎖
select * from table where ?;
-
當(dāng)前讀:特殊的讀操作及插入/更新/刪除操作,屬于當(dāng)前讀序臂,需要加鎖
1 select * from table where ? lock in share mode; 2 select * from table where ? for update; 3 insert into table values (…); 4 update table set ? where ?; 5 delete from table where ?;
快照讀是通過undo log
來實(shí)現(xiàn)多個版本的控制蚌卤。如下圖,每個數(shù)據(jù)行:row_id
為行id贸宏,trx_id
表示最近修改的事務(wù)id造寝,db_roll_ptr
為指向undo segment
中undo log
的指針】粤罚快照讀時诫龙,比較當(dāng)前事務(wù)id與trx_id
的關(guān)系,如果trx_id
小于事務(wù)id鲫咽,則該條數(shù)據(jù)對當(dāng)前事務(wù)可見签赃,反之不可見,不可見時再通過db_roll_ptr
查找歷史版本記錄分尸,取出可見的最近的歷史記錄锦聊。undo log
的鏈路不會很深,后臺purge
線程定期清除無用的歷史版本(在沒有活動事務(wù)依賴時箩绍,undo log
即可被刪除)孔庭。
數(shù)據(jù)恢復(fù)機(jī)制
數(shù)據(jù)恢復(fù)主要分為以下幾個步驟:
- 首先檢查最近的Checkpoint,在RedoLog中將Checkpoint起始到目前的已提交狀態(tài)的行數(shù)據(jù)提交到盤材蛛,并將回滾狀態(tài)的通過在undolog日志中查找相應(yīng)的行數(shù)據(jù)恢復(fù)
- 將未提交或者為回滾的則通過在undolog日志中查找相應(yīng)的行數(shù)據(jù)恢復(fù)
表優(yōu)化
當(dāng)單表記錄數(shù)過大時圆到,數(shù)據(jù)庫的CRUD
性能會明顯下降,所以有以下方案來解決卑吭。
基礎(chǔ)方案
- 查詢時限定數(shù)據(jù)的范圍
- 讀寫分離:M-S模式芽淡,主庫負(fù)責(zé)寫,從庫負(fù)責(zé)讀
- 緩存技術(shù):使用數(shù)據(jù)庫的緩存豆赏,還可以對重量級挣菲、更新少的數(shù)據(jù)通過應(yīng)用級別的緩存方式解決
除了以上這些,還有下面兩塊比較關(guān)鍵的技術(shù)掷邦。
分表
分表是指數(shù)據(jù)表列的拆分白胀,把一張列比較多的表拆分為多張表。
分表可以使行數(shù)據(jù)變小抚岗,在查詢時減少讀取的Block數(shù)纹笼,減少I/O次數(shù);還可以可以簡化表的結(jié)構(gòu)苟跪,易于維護(hù)廷痘。
但是主鍵會出現(xiàn)冗余蔓涧,需要管理冗余列,并會引起Join操作笋额,當(dāng)然可以通過在應(yīng)用層進(jìn)行Join來解決元暴,并且會讓事務(wù)變得更加復(fù)雜。
分庫
保持?jǐn)?shù)據(jù)表結(jié)構(gòu)不變兄猩,通過某種策略存儲數(shù)據(jù)分片茉盏。這樣每一片數(shù)據(jù)分散到不同的表或者庫中,達(dá)到了分布式的目的枢冤。 分庫(水平拆分)可以支撐非常大的數(shù)據(jù)量鸠姨。
分庫能夠支持非常大的數(shù)據(jù)量存儲,應(yīng)用端改造也少淹真,但分片事務(wù)難以解決讶迁,跨界點(diǎn)Join性能較差,邏輯復(fù)雜核蘸。
PS引用:
http://blog.codinglabs.org/articles/theory-of-mysql-index.html
https://segmentfault.com/a/1190000006158186
寫的有點(diǎn)糙巍糯,歡迎大家批評指正>-<