????????本文是我自己在秋招復(fù)習(xí)時的讀書筆記,整理的知識點(diǎn),也是為了防止忘記,尊重勞動成果,轉(zhuǎn)載注明出處哦!如果你也喜歡,那就點(diǎn)個小心心,文末贊賞一杯豆奶吧,嘻嘻。 讓我們共同成長吧……
MySQL數(shù)據(jù)庫知識點(diǎn)整理
????1.常用基礎(chǔ)SQL
????2.優(yōu)化事項(xiàng)
????????1. 對查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。
????????2. 應(yīng)盡量避免在 where 子句中對字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:select id from t where num is null可以在num上設(shè)置默認(rèn)值0,確保表中num列沒有null值,然后這樣查詢:select id from t where num=0
????????3. 應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則引擎將放棄使用索引而進(jìn)行全表掃描。
????????4. 應(yīng)盡量避免在 where 子句中使用or 來連接條件,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:select id from t where num=10 or num=20可以這樣查詢:select id from t where num=10 union all select id from t where num=20
????????5. in 和 not in 也要慎用,否則會導(dǎo)致全表掃描,如:select id from t where num in(1,2,3) 對于連續(xù)的數(shù)值,能用 between 就不要用 in 了:select id from t where num between 1 and 3
????????6. 下面的查詢也將導(dǎo)致全表掃描:select id from t where name like ‘%李%'若要提高效率,可以考慮全文檢索。
????????7. 如果在 where 子句中使用參數(shù),也會導(dǎo)致全表掃描。因?yàn)镾QL只有在運(yùn)行時才會解析局部變量,但優(yōu)化程序不能將訪問計劃的選擇推遲到運(yùn)行時;它必須在編譯時進(jìn)行選擇。然 而,如果在編譯時建立訪問計劃,變量的值還是未知的,因而無法作為索引選擇的輸入項(xiàng)。如下面語句將進(jìn)行全表掃描:select id from t where num=@num可以改為強(qiáng)制查詢使用索引:select id from t with(index(索引名)) where num=@num
????????8. 應(yīng)盡量避免在 where 子句中對字段進(jìn)行表達(dá)式操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:select id from t where num/2=100應(yīng)改為:select id from t where num=100*2
????????9. 應(yīng)盡量避免在where子句中對字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。如:select id from t where substring(name,1,3)='abc' ,name以abc開頭的id應(yīng)改為:select id from t where name like ‘a(chǎn)bc%'
????????10. 不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,否則系統(tǒng)將可能無法正確使用索引。
????????11. 在使用索引字段作為條件時,如果該索引是復(fù)合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使用,并且應(yīng)盡可能的讓字段順序與索引順序相一致。
????????12. 不要寫一些沒有意義的查詢,如需要生成一個空表結(jié)構(gòu):select col1,col2 into #t from t where 1=0 這類代碼不會返回任何結(jié)果集,但是會消耗系統(tǒng)資源的,應(yīng)改成這樣:create table #t(…)
????????13. 很多時候用 exists 代替 in 是一個好的選擇:select num from a where num in(select num from b) 用下面的語句替換:
select num from a where exists(select 1 from b where num=a.num)
???????14. 并不是所有索引對查詢都有效,SQL是根據(jù)表中數(shù)據(jù)來進(jìn)行查詢優(yōu)化的,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時,SQL查詢可能不會去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對查詢效率起不了作用。
????????15. 索引并不是越多越好,索引固然可 以提高相應(yīng)的 select 的效率,但同時也降低了 insert 及 update 的效率,因?yàn)?insert 或 update 時有可能會重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個表的索引數(shù)最好不要超過6個,若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有 必要。
????????16. 應(yīng)盡可能的避免更新 clustered 索引數(shù)據(jù)列,因?yàn)?clustered 索引數(shù)據(jù)列的順序就是表記錄的物理存儲順序,一旦該列值改變將導(dǎo)致整個表記錄的順序的調(diào)整,會耗費(fèi)相當(dāng)大的資源。若應(yīng)用系統(tǒng)需要頻繁更新 clustered 索引數(shù)據(jù)列,那么需要考慮是否應(yīng)將該索引建為 clustered 索引。
????????17. 盡量使用數(shù)字型字段,若只含數(shù)值信息的字段盡量不要設(shè)計為字符型,這會降低查詢和連接的性能,并會增加存儲開銷。這是因?yàn)橐嬖谔幚聿樵兒瓦B接時會逐個比較字符串中每一個字符,而對于數(shù)字型而言只需要比較一次就夠了。
????????18. 盡可能的使用 varchar/nvarchar 代替 char/nchar ,因?yàn)槭紫茸冮L字段存儲空間小,可以節(jié)省存儲空間,其次對于查詢來說,在一個相對較小的字段內(nèi)搜索效率顯然要高些。
????????19. 任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段。
????????20. 盡量使用表變量來代替臨時表。如果表變量包含大量數(shù)據(jù),請注意索引非常有限(只有主鍵索引)。
????????21. 避免頻繁創(chuàng)建和刪除臨時表,以減少系統(tǒng)表資源的消耗。
????????22. 臨時表并不是不可使用,適當(dāng)?shù)厥褂盟鼈兛梢允鼓承├谈行?,例如,?dāng)需要重復(fù)引用大型表或常用表中的某個數(shù)據(jù)集時。但是,對于一次性事件,最好使用導(dǎo)出表。
????????23. 在新建臨時表時,如果一次性插入數(shù)據(jù)量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果數(shù)據(jù)量不大,為了緩和系統(tǒng)表的資源,應(yīng)先create table,然后insert。
????????24. 如果使用到了臨時表,在存儲過程的最后務(wù)必將所有的臨時表顯式刪除,先 truncate table ,然后 drop table ,這樣可以避免系統(tǒng)表的較長時間鎖定。
????????25. 盡量避免使用游標(biāo),因?yàn)橛螛?biāo)的效率較差,如果游標(biāo)操作的數(shù)據(jù)超過1萬行,那么就應(yīng)該考慮改寫。
????????26. 使用基于游標(biāo)的方法或臨時表方法之前,應(yīng)先尋找基于集的解決方案來解決問題,基于集的方法通常更有效。
????????27. 與臨時表一樣,游標(biāo)并不是不可使 用。對小型數(shù)據(jù)集使用 FAST_FORWARD 游標(biāo)通常要優(yōu)于其他逐行處理方法,尤其是在必須引用幾個表才能獲得所需的數(shù)據(jù)時。在結(jié)果集中包括“合計”的例程通常要比使用游標(biāo)執(zhí)行的速度快。如果開發(fā)時 間允許,基于游標(biāo)的方法和基于集的方法都可以嘗試一下,看哪一種方法的效果更好。
????????28. 在所有的存儲過程和觸發(fā)器的開始處設(shè)置 SET NOCOUNT ON ,在結(jié)束時設(shè)置 SET NOCOUNT OFF 。無需在執(zhí)行存儲過程和觸發(fā)器的每個語句后向客戶端發(fā)送DONE_IN_PROC 消息。
????????29. 盡量避免大事務(wù)操作,提高系統(tǒng)并發(fā)能力。
????????30. 盡量避免向客戶端返回大數(shù)據(jù)量,若數(shù)據(jù)量過大,應(yīng)該考慮相應(yīng)需求是否合理。
1、事務(wù)四大特性(ACID)
????原子性(Atomicity):原子性是指事務(wù)是一個不可分割的工作單位,事務(wù)中的操作要么都發(fā)生,要么都不發(fā)生。
????一致性(Consistency):如果事務(wù)執(zhí)行之前數(shù)據(jù)庫是一個完整性的狀態(tài),那么事務(wù)結(jié)束后,無論事務(wù)是否執(zhí)行成功,數(shù)據(jù)庫仍然是一個完整性狀態(tài)。 (數(shù)據(jù)庫的完整性狀態(tài):當(dāng)一個數(shù)據(jù)庫中的所有的數(shù)據(jù)都符合數(shù)據(jù)庫中所定義的所有的約束,此時可以稱數(shù)據(jù)庫是一個完整性狀態(tài)。)
????隔離性(Isolation):事務(wù)的隔離性是指多個用戶并發(fā)訪問數(shù)據(jù)庫時,一個用戶的事務(wù)不能被其它用戶的事務(wù)所干擾,多個并發(fā)事務(wù)之間數(shù)據(jù)要相互隔離。
????持久性(durability):持久性是指一個事務(wù)一旦被提交,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就是永久性的,接下來即使數(shù)據(jù)庫發(fā)生故障也不應(yīng)該對其有任何影響。
????引申:NOSQL CAP BASE
????1.關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫區(qū)別?
????優(yōu)點(diǎn)
????成本:nosql數(shù)據(jù)庫簡單易部署,基本都是開源軟件,不需要像使用oracle那樣花費(fèi)大量成本購買使用,相比關(guān)系型數(shù)據(jù)庫價格便宜。當(dāng)然還有免費(fèi)的
????查詢速度:nosql數(shù)據(jù)庫將數(shù)據(jù)存儲于緩存之中,關(guān)系型數(shù)據(jù)庫將數(shù)據(jù)存儲在硬盤中,自然查詢速度遠(yuǎn)不及nosql數(shù)據(jù)庫。
????存儲數(shù)據(jù)的格式:nosql的存儲格式是key,value形式、文檔形式、圖片形式等等,所以可以存儲基礎(chǔ)類型以及對象或者是集合等各種格式,而數(shù)據(jù)庫則只支持基礎(chǔ)類型。
????擴(kuò)展性:關(guān)系型數(shù)據(jù)庫有類似join這樣的多表查詢機(jī)制的限制導(dǎo)致擴(kuò)展很艱難。
????缺點(diǎn)
????維護(hù)的工具和資料有限,因?yàn)閚osql是屬于新的技術(shù),不能和關(guān)系型數(shù)據(jù)庫10幾年的技術(shù)同日而語。
????不提供對sql的支持,如果不支持sql這樣的工業(yè)標(biāo)準(zhǔn),將產(chǎn)生一定用戶的學(xué)習(xí)和使用成本。
????不提供關(guān)系型數(shù)據(jù)庫對事物的處理。
????非關(guān)系型數(shù)據(jù)庫的優(yōu)勢
????性能NOSQL是基于鍵值對的,可以想象成表中的主鍵和值的對應(yīng)關(guān)系,而且不需要經(jīng)過SQL層的解析,所以性能非常高。
????可擴(kuò)展性同樣也是因?yàn)榛阪I值對,數(shù)據(jù)之間沒有耦合性,所以非常容易水平擴(kuò)展。
關(guān)系型數(shù)據(jù)庫的優(yōu)勢
????復(fù)雜查詢可以用SQL語句方便的在一個表以及多個表之間做非常復(fù)雜的數(shù)據(jù)查詢。
????事務(wù)支持使得對于安全性能很高的數(shù)據(jù)訪問要求得以實(shí)現(xiàn)。對于這兩類數(shù)據(jù)庫,對方的優(yōu)勢就是自己的弱勢,反之亦然。
2.CAP 分布式系統(tǒng)不可能同時滿足一致性(C:Consistency)、可用性(A:Availability)和分區(qū)容忍性(P:Partition Tolerance),最多只能同時滿足其中兩項(xiàng)
dubbo+zookeeper 主要實(shí)現(xiàn)CP
springcloud eureka [hystrix] 主要實(shí)現(xiàn)AP
以上與服務(wù)注冊細(xì)節(jié)相關(guān)
3.BASE 是基本可用(Basically Available)、軟狀態(tài)(Soft State)和最終一致性(Eventually Consistent)三個短語的縮寫。 BASE 理論是對 CAP 中一致性和可用性權(quán)衡的結(jié)果,它的理論的核心思想是:即使無法做到強(qiáng)一致性,但每個應(yīng)用都可以根據(jù)自身業(yè)務(wù)特點(diǎn),采用適當(dāng)?shù)姆绞絹硎瓜到y(tǒng)達(dá)到最終一致性。
2、數(shù)據(jù)庫隔離級別,每個級別會引發(fā)什么問題,mysql默認(rèn)是哪個級別?
????SQL標(biāo)準(zhǔn)定義了4類隔離級別,包括了一些具體規(guī)則,用來限定事務(wù)內(nèi)外的哪些改變是可見的,哪些是不可見的。低級別的隔離級一般支持更高的并發(fā)處理,并擁有更低的系統(tǒng)開銷。
????Read Uncommitted(讀取未提交內(nèi)容)
????在該隔離級別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌墑e好多少。讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。
????Read Committed(讀取提交內(nèi)容)
????這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡單定義:一個事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變。 這種隔離級別也支持所謂的不可重復(fù)讀(Nonrepeatable Read),因?yàn)橥皇聞?wù)的其他實(shí)例在該實(shí)例處理其間可能會有新的commit,所以同一select可能返回不同結(jié)果。
????Repeatable Read(可重讀)
????這是MySQL的默認(rèn)事務(wù)隔離級別,它確保同一事務(wù)的多個實(shí)例在并發(fā)讀取數(shù)據(jù)時,會看到同樣的數(shù)據(jù)行。不過理論上,這會導(dǎo)致另一個棘手的問題:幻讀 (Phantom Read)。 簡單的說,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時,另一個事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時,會發(fā)現(xiàn)有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)機(jī)制解決了該問題。
????Serializable(可串行化)
????這是最高的隔離級別,它通過強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數(shù)據(jù)行上加上共享鎖。在這個級別,可能導(dǎo)致大量的超時現(xiàn)象和鎖競爭。 這四種隔離級別采取不同的鎖類型來實(shí)現(xiàn),若讀取的是同一個數(shù)據(jù)的話,就容易發(fā)生問題。
????臟讀(Drity Read):某個事務(wù)已更新一份數(shù)據(jù),另一個事務(wù)在此時讀取了同一份數(shù)據(jù),由于某些原因,前一個RollBack了操作,則后一個事務(wù)所讀取的數(shù)據(jù)就會是不正確的。
????不可重復(fù)讀(Non-repeatable read):在一個事務(wù)的兩次查詢之中數(shù)據(jù)不一致,這可能是兩次查詢過程中間插入了一個事務(wù)更新的原有的數(shù)據(jù)。
????幻讀(Phantom Read):在一個事務(wù)的兩次查詢中數(shù)據(jù)筆數(shù)不一致,例如有一個事務(wù)查詢了幾列(Row)數(shù)據(jù),而另一個事務(wù)卻在此時插入了新的幾列數(shù)據(jù),先前的事務(wù)在接下來的查詢中,就會發(fā)現(xiàn)有幾列數(shù)據(jù)是它先前所沒有的。
????讀不影響寫:事務(wù)以排他鎖的形式修改原始數(shù)據(jù),讀時不加鎖,因?yàn)?MySQL 在事務(wù)隔離級別Read committed 、Repeatable Read下,InnoDB 存儲引擎采用非鎖定性一致讀--即讀取不占用和等待表上的鎖。即采用的是MVCC中一致性非鎖定讀模式。 因讀時不加鎖,所以不會阻塞其他事物在相同記錄上加 X鎖來更改這行記錄。
????寫不影響讀:事務(wù)以排他鎖的形式修改原始數(shù)據(jù),當(dāng)讀取的行正在執(zhí)行 delete 或者 update 操作,這時讀取操作不會因此去等待行上鎖的釋放。相反地,InnoDB 存儲引擎會去讀取行的一個快照數(shù)據(jù)。
????間隙鎖:間隙鎖主要用來防止幻讀,用在repeatable-read隔離級別下,指的是當(dāng)對數(shù)據(jù)進(jìn)行條件,范圍檢索時,對其范圍內(nèi)也許并存在的值進(jìn)行加鎖! 當(dāng)查詢的索引含有唯一屬性(唯一索引,主鍵索引)時,Innodb存儲引擎會對next-key lock進(jìn)行優(yōu)化,將其降為record lock,即僅鎖住索引本身,而不是范圍!若是普通輔助索引,則會使用傳統(tǒng)的next-key lock進(jìn)行范圍鎖定!
3、MySQL的鎖算法
????Record Lock:單個行記錄上的鎖。
????Gap Lock:間隙鎖,鎖定一個范圍,但不包括記錄本身。GAP鎖的目的,是為了防止同一事務(wù)的兩次當(dāng)前讀,出現(xiàn)幻讀的情況。
????Next-Key Lock:1+2,鎖定一個范圍,并且鎖定記錄本身。對于行的查詢,都是采用該方法,主要目的是解決幻讀的問題。
4、MySQL的MVCC
????MVCC的全稱是“多版本并發(fā)控制”。這項(xiàng)技術(shù)使得InnoDB的事務(wù)隔離級別下執(zhí)行一致性讀操作有了保證,換言之,就是為了查詢一些正在被另一個事務(wù)更新的行,并且可以看到它們被更新之前的值。 這是一個可以用來增強(qiáng)并發(fā)性的強(qiáng)大的技術(shù),因?yàn)檫@樣的一來的話查詢就不用等待另一個事務(wù)釋放鎖。這項(xiàng)技術(shù)在數(shù)據(jù)庫領(lǐng)域并不是普遍使用的。一些其它的數(shù)據(jù)庫產(chǎn)品,以及mysql其它的存儲引擎并不支持它。
????mysql的innodb采用的是行鎖,而且采用了多版本并發(fā)控制來提高讀操作的性能。
1.什么是多版本并發(fā)控制呢MVCC ?
????其實(shí)就是在每一行記錄的后面增加兩個隱藏列,記錄創(chuàng)建版本號和刪除版本號,而每一個事務(wù)在啟動的時候,都有一個唯一的遞增的版本號。 在InnoDB中,給每行增加兩個隱藏字段來實(shí)現(xiàn)MVCC,兩個列都用來存儲事務(wù)的版本號,每開啟一個新事務(wù),事務(wù)的版本號就會遞增。
2.默認(rèn)的隔離級別(REPEATABLE READ)下,增刪查改?
????SELECT
????讀取創(chuàng)建版本小于或等于當(dāng)前事務(wù)版本號,并且刪除版本為空或大于當(dāng)前事務(wù)版本號的記錄。這樣可以保證在讀取之前記錄是存在的
????INSERT
????將當(dāng)前事務(wù)的版本號保存至行的創(chuàng)建版本號
????UPDATE
????新插入一行,并以當(dāng)前事務(wù)的版本號作為新行的創(chuàng)建版本號,同時將原記錄行的刪除版本號設(shè)置為當(dāng)前事務(wù)版本號
????DELETE
????將當(dāng)前事務(wù)的版本號保存至行的刪除版本號
3.什么是快照讀和當(dāng)前讀?
????快照讀:讀取的是快照版本,也就是歷史版本
????當(dāng)前讀:讀取的是最新版本
????普通的SELECT就是快照讀,而UPDATE、DELETE、INSERT、SELECT …? LOCK IN SHARE MODE、SELECT … FOR UPDATE是當(dāng)前讀。
4.什么是鎖定讀?
????在一個事務(wù)中,標(biāo)準(zhǔn)的SELECT語句是不會加鎖,但是有兩種情況例外。
????SELECT ... LOCK IN SHARE MODE 給記錄假設(shè)共享鎖,這樣一來的話,其它事務(wù)只能讀不能修改,直到當(dāng)前事務(wù)提交
????SELECT ... FOR UPDATE 給索引記錄加鎖,這種情況下跟UPDATE的加鎖情況是一樣的
5.什么是一致性非鎖定讀?
????consistent read (一致性讀),InnoDB用多版本來提供查詢數(shù)據(jù)庫在某個時間點(diǎn)的快照。如果隔離級別是REPEATABLE READ,那么在同一個事務(wù)中的所有一致性讀都讀的是事務(wù)中第一個這樣的讀讀到的快照; 如果是READ COMMITTED,那么一個事務(wù)中的每一個一致性讀都會讀到它自己刷新的快照版本。Consistent read(一致性讀)是READ COMMITTED和REPEATABLE READ隔離級別下普通SELECT語句默認(rèn)的模式。 一致性讀不會給它所訪問的表加任何形式的鎖,因此其它事務(wù)可以同時并發(fā)的修改它們。
????MVCC實(shí)現(xiàn)一致性非鎖定讀,這就有保證在同一個事務(wù)中多次讀取相同的數(shù)據(jù)返回的結(jié)果是一樣的,解決了不可重復(fù)讀的問題。
6.什么是悲觀鎖和樂觀鎖?
????????悲觀鎖:正如它的名字那樣,數(shù)據(jù)庫總是認(rèn)為別人會去修改它所要操作的數(shù)據(jù),因此在數(shù)據(jù)庫處理過程中將數(shù)據(jù)加鎖。其實(shí)現(xiàn)依靠數(shù)據(jù)庫底層。
????????樂觀鎖:如它的名字那樣,總是認(rèn)為別人不會去修改,只有在提交更新的時候去檢查數(shù)據(jù)的狀態(tài)。通常是給數(shù)據(jù)增加一個字段來標(biāo)識數(shù)據(jù)的版本。
7.select時怎么加排它鎖?
????使用鎖定讀,普通select不會引起加鎖,而是去讀取最新的快照。同上4
????事務(wù)以排他鎖的形式修改原始數(shù)據(jù),當(dāng)讀取的數(shù)據(jù)正在進(jìn)行更新等操作,則直接去讀取快照,而不是等鎖釋放
5、MYSQL的兩種存儲引擎區(qū)別(事務(wù)、鎖級別等等),各自的適用場景
MyISAM
????不支持事務(wù),但是每次查詢都是原子的;
????支持表級鎖,即每次操作是對整個表加鎖;
????存儲表的總行數(shù);
????一個MYISAM表有三個文件:索引文件、表結(jié)構(gòu)文件、數(shù)據(jù)文件;
????采用非聚集索引,索引文件的數(shù)據(jù)域存儲指向數(shù)據(jù)文件的指針。輔索引與主索引基本一致,但是輔索引不用保證唯一性。
????適用OLAP
InnoDb
????支持ACID的事務(wù),支持事務(wù)的四種隔離級別;
????支持行級鎖及外鍵約束:因此可以支持寫并發(fā);
不存儲總行數(shù);
????一個InnoDb引擎存儲在一個文件空間(共享表空間,表大小不受操作系統(tǒng)控制,一個表可能分布在多個文件里),也有可能為多個(設(shè)置為獨(dú)立表空,表大小受操作系統(tǒng)文件大小限制,一般為2G),受操作系統(tǒng)文件大小的限制;
????主鍵索引采用聚集索引(索引的數(shù)據(jù)域存儲數(shù)據(jù)文件本身),輔索引的數(shù)據(jù)域存儲主鍵的值;因此從輔索引查找數(shù)據(jù),需要先通過輔索引找到主鍵值,再訪問輔索引;
????最好使用自增主鍵,防止插入數(shù)據(jù)時,為維持B+樹結(jié)構(gòu),文件的大調(diào)整。
????適用OLTP
InnoDB主要特性
????主要包括:插入緩存(insert buffer)、兩次寫(double write)、自適應(yīng)哈希(Adaptive Hash index)、異步IO(Async IO)、刷新鄰接頁(Flush Neighbor Page)
感興趣可以參考書籍《MySQL技術(shù)內(nèi)幕:innodb存儲引擎》 網(wǎng)上找了一個博客InnoDB關(guān)鍵特性
6、索引有B+索引和hash索引,各自的區(qū)別?
主要區(qū)別
????如果是等值查詢,那么哈希索引明顯有絕對優(yōu)勢,因?yàn)橹恍枰?jīng)過一次算法即可找到相應(yīng)的鍵值;當(dāng)然了,這個前提是,鍵值都是唯一的。如果鍵值不是唯一的,就需要先找到該鍵所在位置,然后再根據(jù)鏈表往后掃描,直到找到相應(yīng)的數(shù)據(jù);
????如果是范圍查詢檢索,這時候哈希索引就毫無用武之地了,因?yàn)樵仁怯行虻逆I值,經(jīng)過哈希算法后,有可能變成不連續(xù)的了,就沒辦法再利用索引完成范圍查詢檢索;
????同理,哈希索引也沒辦法利用索引完成排序,以及l(fā)ike ‘xxx%’ 這樣的部分模糊查詢(這種部分模糊查詢,其實(shí)本質(zhì)上也是范圍查詢);
????哈希索引也不支持多列聯(lián)合索引的最左匹配規(guī)則;
????+樹索引的關(guān)鍵字檢索效率比較平均,不像B樹那樣波動幅度大,在有大量重復(fù)鍵值情況下,哈希索引的效率也是極低的,因?yàn)榇嬖谒^的哈希碰撞問題。
7、為什么B+樹適合作為索引的結(jié)構(gòu)?
????B樹:有序數(shù)組+平衡多叉樹
????B+樹:有序數(shù)組鏈表+平衡多叉樹 葉子存儲數(shù)據(jù),空間占用小,且是雙鏈表,修改效率快
????不同于B樹只適合隨機(jī)檢索,B+樹同時支持隨機(jī)檢索和順序檢索
????數(shù)據(jù)庫索引采用B+樹的主要原因是B樹在提高了磁盤IO性能的同時并沒有解決元素遍歷的效率低下的問題。 正是為了解決這個問題,B+樹應(yīng)運(yùn)而生。B+樹只要遍歷葉子節(jié)點(diǎn)就可以實(shí)現(xiàn)整棵樹的遍歷。而且在數(shù)據(jù)庫中基于范圍的查詢是非常頻繁的,而B樹不支持這樣的操作(或者說效率太低)。
????平衡二叉樹沒能充分利用磁盤預(yù)讀功能,而B樹是為了充分利用磁盤預(yù)讀功能來而創(chuàng)建的一種數(shù)據(jù)結(jié)構(gòu),也就是說B樹就是為了作為索引才被發(fā)明出來的的。
1.局部性原理與磁盤預(yù)讀
????由于存儲介質(zhì)的特性,磁盤本身存取就比主存慢很多,再加上機(jī)械運(yùn)動耗費(fèi),磁盤的存取速度往往是主存的幾百分分之一,因此為了提高效率,要盡量減少磁盤I/O。 為了達(dá)到這個目的,磁盤往往不是嚴(yán)格按需讀取,而是每次都會預(yù)讀,即使只需要一個字節(jié),磁盤也會從這個位置開始,順序向后讀取一定長度的數(shù)據(jù)放入內(nèi)存。這樣做的理論依據(jù)是計算機(jī)科學(xué)中著名的局部性原理:
????當(dāng)一個數(shù)據(jù)被用到時,其附近的數(shù)據(jù)也通常會馬上被使用。 程序運(yùn)行期間所需要的數(shù)據(jù)通常比較集中。 由于磁盤順序讀取的效率很高(不需要尋道時間,只需很少的旋轉(zhuǎn)時間),因此對于具有局部性的程序來說,預(yù)讀可以提高I/O效率。
2.為什么說紅黑樹沒能充分利用磁盤預(yù)讀功能?
????紅黑樹這種結(jié)構(gòu),h明顯要深的多。由于邏輯上很近的節(jié)點(diǎn)(父子)物理上可能很遠(yuǎn),無法利用局部性,所以紅黑樹的I/O漸進(jìn)復(fù)雜度也為O(h),效率明顯比B-Tree差很多。
????也就是說,使用紅黑樹(平衡二叉樹)結(jié)構(gòu)的話,每次磁盤預(yù)讀中的很多數(shù)據(jù)是用不上的數(shù)據(jù)。因此,它沒能利用好磁盤預(yù)讀的提供的數(shù)據(jù)。然后又由于深度大(較B樹而言),所以進(jìn)行的磁盤IO操作更多。
8、B+索引數(shù)據(jù)結(jié)構(gòu),和B樹的區(qū)別 ?
????除了以上的,主要區(qū)別,其他請看B- B+ B*樹?實(shí)際上B-就是B樹,二叉樹不叫B樹,像這種寫法B-Tree,可以是B-樹也可以說是B樹[-可能是連接符,可能是翻譯問題],B+ B* 是改善的B樹
9、索引的分類(主鍵索引、唯一索引),最左前綴原則,哪些情況索引會失效?
????????1.關(guān)于索引優(yōu)化最前面已有了,不再羅列
????????2.各種索引區(qū)別
????????普通索引:最基本的索引,沒有任何限制。
????????唯一索引:與"普通索引"類似,不同的就是:索引列的值必須唯一,但允許有空值。
????????主鍵索引:它 是一種特殊的唯一索引,不允許有空值。
????????全文索引:僅可用于 MyISAM 表,針對較大的數(shù)據(jù),生成全文索引很耗時耗空間。
????????組合索引:為了更多的提高mysql效率可建立組合索引,遵循”最左前綴“原則。
10、聚集索引和非聚集索引區(qū)別是什么?
????聚集(clustered)索引,也叫聚簇索引。
????????定義:數(shù)據(jù)行的物理順序與列值(一般是主鍵的那一列)的邏輯順序相同,一個表中只能擁有一個聚集索引。
????非聚集(unclustered)索引。
????????定義:該索引中索引的邏輯順序與磁盤上行的物理存儲順序不同,一個表中可以擁有多個非聚集索引。
????總結(jié)
????????使用聚集索引的查詢效率要比非聚集索引的效率要高,但是如果需要頻繁去改變聚集索引的值,寫入性能并不高,因?yàn)樾枰苿訉?yīng)數(shù)據(jù)的物理位置。
????非聚集索引在查詢的時候可以的話就避免二次查詢,這樣性能會大幅提升。
????????不是所有的表都適合建立索引,只有數(shù)據(jù)量大表才適合建立索引,且建立在選擇性高的列上面性能會更好。
????????重復(fù)度高的可能使得索引失效
????????具體最前面有更詳細(xì)的????
11、schema(表結(jié)構(gòu))對性能的影響?
1.冗余數(shù)據(jù)的處理
????適當(dāng)?shù)臄?shù)據(jù)冗余可以提高系統(tǒng)的整體查詢性能(在P2P中,在userinfo對象中有realname和idnumber);
關(guān)系數(shù)據(jù)庫的三范式:
????第一范式(1NF)是對關(guān)系模式的基本要求,不滿足第一范式(1NF)的數(shù)據(jù)庫就不是關(guān)系數(shù)據(jù)庫,是指數(shù)據(jù)庫表的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中不能有多個值;
????第二范式(2NF)要求數(shù)據(jù)庫表中的每個實(shí)例或行必須可以被惟一地區(qū)分。 即各字段和主鍵之間不存在部分依賴
????第三范式(3NF)要求一個數(shù)據(jù)庫表中不包含已在其它表中已包含的非主關(guān)鍵字信息。即在第二范式的基礎(chǔ)上,不存在傳遞依賴 (不允許有冗余數(shù)據(jù))
2.大表拆小表,有大數(shù)據(jù)的列單獨(dú)拆成小表
????在一個數(shù)據(jù)庫中,一般不會設(shè)計屬性過多的表;
????在一個數(shù)據(jù)庫中,一般不會有超過500/1000萬數(shù)據(jù)的表(拆表,按照邏輯拆分,按照業(yè)務(wù)拆分);
????有大數(shù)據(jù)的列單獨(dú)拆成小表(富文本編輯器,CKeditor);
3.根據(jù)需求的展示設(shè)置更合理的表結(jié)構(gòu)
4.把常用屬性分離成小表
????在P2P項(xiàng)目中,我們把logininfo和userinfo和account表拆成了三張表;
????減少查詢常用屬性需要查詢的列;
????便于常用屬性的集中緩存;
12、數(shù)據(jù)庫的主從復(fù)制 ?
????就算MYSQL拆成了多個,也必須分出主和從,所有的寫操作都必須要在主MYSQL 上完成;
????所有的從MYSQL的數(shù)據(jù)都來自于(同步于)主MYSQL;
????既然涉及到同步,那一定有延遲;有延遲,就一定可能在讀的時候產(chǎn)生臟數(shù)據(jù);所以,能夠在從MYSQL上進(jìn)行的讀操作,一定對實(shí)時性和臟數(shù)據(jù)有一定容忍度的數(shù)據(jù);比如,登陸日志,后臺報表,首頁統(tǒng)計信息來源;文章;資訊;SNS消息;
????在我們的P2P中,做主從,絕大部分的讀操作,都必須在主MYSQL上執(zhí)行;只有(登陸日志,報表,滿標(biāo)一審列表,滿標(biāo)二審列表,用戶的流水信息,充值明細(xì),投標(biāo)明細(xì)查詢類的業(yè)務(wù)可以定位到從MYSQL);
????【一定注意】:在MYSQL主從時,如果一個業(yè)務(wù)(service中的一個方法)中,如果既有R操作,又有W操作,因?yàn)閃操作一定要在主MYSQL上,所以在一個事務(wù)中所有的數(shù)據(jù)來源都只能來自于一個MYSQL
????要完成主從同步,就必須讓在Master上執(zhí)行的所有的DML和DDL能夠正確的在Salve上再執(zhí)行一遍;MYSQL選擇使用文件來記錄SQL;
????完成主從同步,第一個事情就是把在主服務(wù)器上的bin-log(二進(jìn)制文件)打開,bin-log文件就可以記錄在MYSQL上執(zhí)行的所有的DML+DDL+TCL;
????MYSQL使用被動注冊的方式來讓從MYSQL請求同步主MYSQL的binlog;原因:被動請求的方式,主的MYSQL不需要知道有哪些從的MYSQL,我額外添加/去掉從MYSQL服務(wù)器,對主MYSQL服務(wù)器的正常運(yùn)行沒有任何影響;
????第二步,從MYSQL后臺一個線程發(fā)送一個請求,到主服務(wù)器請求更新數(shù)據(jù);最重要的數(shù)據(jù)(我這次請求,請求你bin-log的哪一行數(shù)據(jù)之后的數(shù)據(jù))
????第三步,主MYSQL后臺一個線程接收到從MYSQL發(fā)送的請求,然后讀取bin-log文件中指定的內(nèi)容,并放在從MYSQL的請求響應(yīng)中;
????第四步,從MYSQL的請求帶回同步的數(shù)據(jù),然后寫在從MYSQL中的relay-log(重做日志)中;relay-log中記錄的就是從主MYSQL中請求回來的哪些SQL數(shù)據(jù);
????第五步,從MYSQL后臺一個線程專門用于從relay-log中讀取同步回來的SQL,并寫入到從MYSQL中,完成同步;
????MYSQL的主從同步是經(jīng)過高度優(yōu)化的,性能非常高;
這里東西太多,更多請參考mysql優(yōu)化的課程筆記
13、explain和join
EXPLAIN:
使用方式: explain SQL;
返回結(jié)果:
ID:執(zhí)行查詢的序列號;
select_type:使用的查詢類型
DEPENDENT SUBQUERY:子查詢中內(nèi)層的第一個SELECT,依賴于外部查詢的結(jié)果集;
DEPENDENT UNION:子查詢中的UNION,且為UNION 中從第二個SELECT 開始的后面所有SELECT,同樣依賴于外部查詢的結(jié)果集;
PRIMARY:子查詢中的最外層查詢,注意并不是主鍵查詢;
SIMPLE:除子查詢或者UNION 之外的其他查詢;
SUBQUERY:子查詢內(nèi)層查詢的第一個SELECT,結(jié)果不依賴于外部查詢結(jié)果集;
UNCACHEABLE SUBQUERY:結(jié)果集無法緩存的子查詢;
UNION:UNION 語句中第二個SELECT 開始的后面所有SELECT,第一個SELECT 為PRIMARY
UNION RESULT:UNION 中的合并結(jié)果;
table:這次查詢訪問的數(shù)據(jù)表;
type:對表所使用的訪問方式:
all:全表掃描
const:讀常量,且最多只會有一條記錄匹配,由于是常量,所以實(shí)際上只需要讀一次;
eq_ref:最多只會有一條匹配結(jié)果,一般是通過主鍵或者唯一鍵索引來訪問;
fulltext:全文檢索,針對full text索引列;
index:全索引掃描;
index_merge:查詢中同時使用兩個(或更多)索引,然后對索引結(jié)果進(jìn)行merge 之后再讀取表數(shù)據(jù);
index_subquery:子查詢中的返回結(jié)果字段組合是一個索引(或索引組合),但不是一個主鍵或者唯一索引;
rang:索引范圍掃描;
ref:Join 語句中被驅(qū)動表索引引用查詢;
ref_or_null:與ref 的唯一區(qū)別就是在使用索引引用查詢之外再增加一個空值的查詢;
system:系統(tǒng)表,表中只有一行數(shù)據(jù);
unique_subquery:子查詢中的返回結(jié)果字段組合是主鍵或者唯一約束;
possible_keys:可選的索引;如果沒有使用索引,為null;
key:最終選擇的索引;
key_len:被選擇的索引長度;
ref:過濾的方式,比如const(常量),column(join),func(某個函數(shù));
rows:查詢優(yōu)化器通過收集到的統(tǒng)計信息估算出的查詢條數(shù);
Extra:查詢中每一步實(shí)現(xiàn)的額外細(xì)節(jié)信息
Distinct:查找distinct 值,所以當(dāng)mysql 找到了第一條匹配的結(jié)果后,將停止該值的查詢而轉(zhuǎn)為后面其他值的查詢;
Full scan on NULL key:子查詢中的一種優(yōu)化方式,主要在遇到無法通過索引訪問null值的使用使用;
Impossible WHERE noticed after reading const tables:MySQL Query Optimizer 通過收集到的統(tǒng)計信息判斷出不可能存在結(jié)果;
No tables:Query 語句中使用FROM DUAL 或者不包含任何FROM 子句;
Not exists:在某些左連接中MySQL Query Optimizer 所通過改變原有Query 的組成而使用的優(yōu)化方法,可以部分減少數(shù)據(jù)訪問次數(shù);
Select tables optimized away:當(dāng)我們使用某些聚合函數(shù)來訪問存在索引的某個字段的時候,MySQL Query Optimizer 會通過索引而直接一次定位到所需的數(shù)據(jù)行完成整個查詢。當(dāng)然,前提是在Query 中不能有GROUP BY 操作。如使用MIN()或者M(jìn)AX()的時候;
Using filesort:當(dāng)我們的Query 中包含ORDER BY 操作,而且無法利用索引完成排序操作的時候,MySQL Query Optimizer 不得不選擇相應(yīng)的排序算法來實(shí)現(xiàn)。
Using index:所需要的數(shù)據(jù)只需要在Index 即可全部獲得而不需要再到表中取數(shù)據(jù);
Using index for group-by:數(shù)據(jù)訪問和Using index 一樣,所需數(shù)據(jù)只需要讀取索引即可,而當(dāng)Query 中使用了GROUP BY 或者DISTINCT 子句的時候,如果分組字段也在索引中,Extra 中的信息就會是Using index for group-by;
Using temporary:當(dāng)MySQL 在某些操作中必須使用臨時表的時候,在Extra 信息中就會出現(xiàn)Using temporary 。主要常見于GROUP BY 和ORDER BY 等操作中。
Using where:如果我們不是讀取表的所有數(shù)據(jù),或者不是僅僅通過索引就可以獲取所有需要的數(shù)據(jù),則會出現(xiàn)Using where 信息;
Using where with pushed condition:這是一個僅僅在NDBCluster 存儲引擎中才會出現(xiàn)的信息,而且還需要通過打開Condition Pushdown 優(yōu)化功能才可能會被使用??刂茀?shù)為engine_condition_pushdown 。
profiling: Query Profiler是MYSQL5.1之后提供的一個很方便的用于診斷Query執(zhí)行的工具,能夠準(zhǔn)確的獲取一條查詢執(zhí)行過程中的CPU,IO等情況;
開啟profiling:set profiling=1
執(zhí)行QUERY,在profiling過程中所有的query都可以記錄下來
查看記錄的query:show profiles
選擇要查看的profile:show profile cpu, block io for query 6
status是執(zhí)行SQL的詳細(xì)過程
Duration:執(zhí)行的具體時間
CPU_user:用戶CPU時間
CPU_system:系統(tǒng)CPU時間
Block_ops_in:IO輸入次數(shù)
Block_ops_out:IO輸出次數(shù)
profiling只對本次會話有效
JOIN的原理
????????在mysql中使用Nested Loop Join來實(shí)現(xiàn)join; A JOIN B:通過A表的結(jié)果集作為循環(huán)基礎(chǔ),一條一條的通過結(jié)果集中的數(shù)據(jù)作為過濾條件到下一個表中查詢數(shù)據(jù),然后合并結(jié)果;
JOIN的優(yōu)化原則
????盡可能減少Join 語句中的Nested Loop 的循環(huán)總次數(shù),用小結(jié)果集驅(qū)動大結(jié)果集;
????優(yōu)先優(yōu)化Nested Loop 的內(nèi)層循環(huán);
????保證Join 語句中被驅(qū)動表上Join 條件字段已經(jīng)被索引;
????擴(kuò)大join buffer的大小;
14、內(nèi)連接、外連接、交叉連接、笛卡兒積等
內(nèi)連接?
????????只有兩個表相匹配的行才能在結(jié)果集中出現(xiàn) 分為三種:等值連接、自然連接、不等連接?
外連接?
????????左外連接(LEFT OUTER JOIN或LEFT JOIN) 以左邊為準(zhǔn),右邊沒用則為空
????????右外連接(RIGHT OUTER JOIN或RIGHT JOIN) 以右邊為準(zhǔn),左邊沒有則為空
????????全外連接(FULL OUTER JOIN或FULL JOIN) 左右均可能為空?
交叉連接
????????沒有WHERE 子句,它返回連接表中所有數(shù)據(jù)行的笛卡爾積?
笛卡兒積
15、死鎖怎么解決?
產(chǎn)生死鎖的原因主要是
????????系統(tǒng)資源不足。
????????進(jìn)程運(yùn)行推進(jìn)的順序不合適。
????????資源分配不當(dāng)?shù)取?/p>
????????如果系統(tǒng)資源充足,進(jìn)程的資源請求都能夠得到滿足,死鎖出現(xiàn)的可能性就很低,否則就會因爭奪有限的資源而陷入死鎖。其次,進(jìn)程運(yùn)行推進(jìn)順序與速度不同,也可能產(chǎn)生死鎖。
產(chǎn)生死鎖的四個必要條件
????????1. 互斥條件:一個資源每次只能被一個進(jìn)程使用。
????????2. 請求與保持條件:一個進(jìn)程因請求資源而阻塞時,對已獲得的資源保持不放。
????????3. 不剝奪條件:進(jìn)程已獲得的資源,在末使用完之前,不能強(qiáng)行剝奪。
????????4. 循環(huán)等待條件:若干進(jìn)程之間形成一種頭尾相接的循環(huán)等待資源關(guān)系。
這四個條件是死鎖的必要條件,只要系統(tǒng)發(fā)生死鎖,這些條件必然成立,而只要上述條件之一不滿足,就不會發(fā)生死鎖。
死鎖的預(yù)防和解除
????????理解了死鎖的原因,尤其是產(chǎn)生死鎖的四個必要條件,就可以最大可能地避免、預(yù)防和解除死鎖。所以,在系統(tǒng)設(shè)計、進(jìn)程調(diào)度等方面注意如何不讓這四個必要條件成立,如何確定資源的合理分配算法,避免進(jìn)程永久占據(jù)系統(tǒng)資源。此外,也要防止進(jìn)程在處于等待狀態(tài)的情況下占用資源,在系統(tǒng)運(yùn)行過程中,對進(jìn)程發(fā)出的每一個系統(tǒng)能夠滿足的資源申請進(jìn)行動態(tài)檢查,并根據(jù)檢查結(jié)果決定是否分配資源,若分配后系統(tǒng)可能發(fā)生死鎖,則不予分配,否則予以分配 。因此,對資源的分配要給予合理的規(guī)劃。 如何將死鎖減至最少
????????雖然不能完全避免死鎖,但可以使死鎖的數(shù)量減至最少。將死鎖減至最少可以增加事務(wù)的吞吐量并減少系統(tǒng)開銷,因?yàn)橹挥泻苌俚氖聞?wù)回滾,而回滾會取消事務(wù)執(zhí)行的所有工作。由于死鎖時回滾而由應(yīng)用程序重新提交。
下列方法有助于最大限度地降低死鎖
????按同一順序訪問對象。
????避免事務(wù)中的用戶交互。
????保持事務(wù)簡短并在一個批處理中。
????使用低隔離級別。
????使用綁定連接。
具體
????????按同一順序訪問對象 -- 如果所有并發(fā)事務(wù)按同一順序訪問對象,則發(fā)生死鎖的可能性會降低。例如,如果兩個并發(fā)事務(wù)獲得 Supplier 表上的鎖,然后獲得 Part 表上的鎖,則在其中一個事務(wù)完成之前,另一個事務(wù)被阻塞在 Supplier 表上。第一個事務(wù)提交或回滾后,第二個事務(wù)繼續(xù)進(jìn)行。不發(fā)生死鎖。將存儲過程用于所有的數(shù)據(jù)修改可以標(biāo)準(zhǔn)化訪問對象的順序。
????????避免事務(wù)中的用戶交互 -- 避免編寫包含用戶交互的事務(wù),因?yàn)檫\(yùn)行沒有用戶交互的批處理的速度要遠(yuǎn)遠(yuǎn)快于用戶手動響應(yīng)查詢的速度,例如答復(fù)應(yīng)用程序請求參數(shù)的提示。例如,如果事務(wù)正在等待用戶輸入,而用戶去吃午餐了或者甚至回家過周末了,則用戶將此事務(wù)掛起使之不能完成。這樣將降低系統(tǒng)的吞吐量,因?yàn)槭聞?wù)持有的任何鎖只有在事務(wù)提交或回滾時才會釋放。即使不出現(xiàn)死鎖的情況,訪問同一資源的其它事務(wù)也會被阻塞,等待該事務(wù)完成。
????????保持事務(wù)簡短并在一個批處理中 -- 在同一數(shù)據(jù)庫中并發(fā)執(zhí)行多個需要長時間運(yùn)行的事務(wù)時通常發(fā)生死鎖。事務(wù)運(yùn)行時間越長,其持有排它鎖或更新鎖的時間也就越長,從而堵塞了其它活動并可能導(dǎo)致死鎖。 保持事務(wù)在一個批處理中,可以最小化事務(wù)的網(wǎng)絡(luò)通信往返量,減少完成事務(wù)可能的延遲并釋放鎖。
????????使用低隔離級別 -- 確定事務(wù)是否能在更低的隔離級別上運(yùn)行。執(zhí)行提交讀允許事務(wù)讀取另一個事務(wù)已讀取(未修改)的數(shù)據(jù),而不必等待第一個事務(wù)完成。使用較低的隔離級別(例如提交讀)而不使用較高的隔離級別(例如可串行讀)可以縮短持有共享鎖的時間,從而降低了鎖定爭奪。
????????使用綁定連接 -- 使用綁定連接使同一應(yīng)用程序所打開的兩個或多個連接可以相互合作。次級連接所獲得的任何鎖可以象由主連接獲得的鎖那樣持有,反之亦然,因此不會相互阻塞。
16、varchar和char的使用場景?
1.varchar的特點(diǎn)
????????存儲變長字符串,只占用必要的存儲空間
????????列的長度小于255,只用額外的1個字節(jié)來記錄長度
????????列的長度大于255,只用額外的2個字節(jié)來記錄長度
2.char的特點(diǎn)
????????存儲定長字符串,最大為255字節(jié)
????????要刪除字符串末尾的空格。
3.如何區(qū)別使用常場景
????????一、根據(jù)字符的長度來判斷。如某個字段,像人的名字,其最長的長度也是有限的。如我們給其分配18個字符長度即可。此時雖然每個人的名字長度有可能 不同,但是即使為其分配了固定長度的字符類型,即18個字符長度,最后浪費(fèi)的空間也不是很大。而如果采用NVARCHAR數(shù)據(jù)類型時,萬一以后需要改名, 而原先的存儲空間不足用來容納新的值,反而會造成一些額外的工作。在這種情況下,進(jìn)行均衡時,會認(rèn)為采用CHAR固定長度的數(shù)據(jù)類型更好。 在實(shí)際項(xiàng)目中, 如果某個字段的字符長度比較短此時一般是采用固定字符長度。
????????二、是考慮其長度的是否相近。如果某個字段其長度雖然比較長,但是其長度總是近似的,如一般在90個到100個字符之間,甚至是相同的長度。此時比較 適合采用CHAR字符類型。比較典型的應(yīng)用就是MD5哈希值。當(dāng)利用MD5哈希值來存儲用戶密碼時,就非常使用采用CHAR字符類型。因?yàn)槠溟L度是相同 的。另外,像用來存儲用戶的身份證號碼等等,一般也建議使用CHAR類型的數(shù)據(jù)。 另外請大家考慮一個問題,CHAR(1)與VARCHAR(1)兩這個定義,會有什么區(qū)別呢?雖然這兩個都只能夠用來保存單個的字符,但是 VARCHAR要比CHAR多占用一個存儲位置。這主要是因?yàn)槭褂肰ARCHAR數(shù)據(jù)類型時,會多用1個字節(jié)用來存儲長度信息。這個管理上的開銷CHAR 字符類型是沒有的。
????????三、從碎片角度進(jìn)行考慮。使用CHAR字符型時,由于存儲空間都是一次性分配的。為此某個字段的內(nèi)容,其都是存儲在一起的。單從這個角度來講,其不 存在碎片的困擾。而可變長度的字符數(shù)據(jù)類型,其存儲的長度是可變的。當(dāng)其更改前后數(shù)據(jù)長度不一致時,就不可避免的會出現(xiàn)碎片的問題。故使用可變長度的字符 型數(shù)據(jù)時,數(shù)據(jù)庫管理員要時不時的對碎片進(jìn)行整理。如執(zhí)行數(shù)據(jù)庫導(dǎo)出導(dǎo)入作業(yè),來消除碎片。
????????四、即使使用Varchar數(shù)據(jù)類型,也不能夠太過于慷慨。這是什么意思呢?如現(xiàn)在用戶需要存儲一個地址信息。根據(jù)評估,只要使用100個字符就可 以了。但是有些數(shù)據(jù)庫管理員會認(rèn)為,反正Varchar數(shù)據(jù)類型是根據(jù)實(shí)際的需要來分配長度的。還不如給其大一點(diǎn)的呢。為此他們可能會為這個字段一次性分 配200個字符的存儲空間。這VARCHAR(100)與VARCHAR(200)真的相同嗎?結(jié)果是否定的。 雖然他們用來存儲90個字符的數(shù)據(jù),其存儲 空間相同。但是對于內(nèi)存的消耗是不同的。對于VARCHAR數(shù)據(jù)類型來說,硬盤上的存儲空間雖然都是根據(jù)實(shí)際字符長度來分配存儲空間的,但是對于內(nèi)存來 說,則不是。其時使用固定大小的內(nèi)存塊來保存值。簡單的說,就是使用字符類型中定義的長度,即200個字符空間。顯然,這對于排序或者臨時表(這些內(nèi)容都 需要通過內(nèi)存來實(shí)現(xiàn))作業(yè)會產(chǎn)生比較大的不利影響。 所以如果某些字段會涉及到文件排序或者基于磁盤的臨時表時,分配VARCHAR數(shù)據(jù)類型時仍然不能夠太 過于慷慨。還是要評估實(shí)際需要的長度,然后選擇一個最長的字段來設(shè)置字符長度。如果為了考慮冗余,可以留10%左右的字符長度。千萬不能認(rèn)為其為根據(jù)實(shí)際 長度來分配存儲空間,而隨意的分配長度,或者說干脆使用最大的字符長度。
17、mysql并發(fā)情況下怎么解決?
????????代碼中sql語句優(yōu)化; 數(shù)據(jù)庫字段優(yōu)化,索引優(yōu)化;加緩存,redis/memcache等;主從,讀寫分離 集群 分流 橫向擴(kuò)展;分區(qū);垂直拆分,解耦模塊;水平切分 分片
18、引申 Redis | Memcached
????Redis
????redis數(shù)據(jù)結(jié)構(gòu)有哪些?
????redis隊(duì)列應(yīng)用場景?
????redis和Memcached(支持?jǐn)?shù)據(jù)持久化)?
????分布式使用場景(儲存session等)
????發(fā)布/訂閱使用場景
以上參考《redis in action》?