面試必看拉队!憑借著這份 MySQL 高頻面試題弊知,我拿到了京東,字節(jié)的offer粱快!

前言

本文主要受眾為開發(fā)人員,所以不涉及到MySQL的服務(wù)部署等操作,且內(nèi)容較多,大家準(zhǔn)備好耐心和瓜子礦泉水.

前一陣系統(tǒng)的學(xué)習(xí)了一下MySQL,也有一些實(shí)際操作經(jīng)驗(yàn),偶然看到一篇和MySQL相關(guān)的面試文章,發(fā)現(xiàn)其中的一些問題自己也回答不好,雖然知識(shí)點(diǎn)大部分都知道,但是無法將知識(shí)串聯(lián)起來.

因此決定搞一個(gè)MySQL靈魂100問,試著用回答問題的方式,讓自己對(duì)知識(shí)點(diǎn)的理解更加深入一點(diǎn).

索引相關(guān)

關(guān)于MySQL的索引,曾經(jīng)進(jìn)行過一次總結(jié),文章鏈接在這里 Mysql索引原理及其優(yōu)化.

1. 什么是索引?

索引是一種數(shù)據(jù)結(jié)構(gòu),可以幫助我們快速的進(jìn)行數(shù)據(jù)的查找.

2. 索引是個(gè)什么樣的數(shù)據(jù)結(jié)構(gòu)呢?

索引的數(shù)據(jù)結(jié)構(gòu)和具體存儲(chǔ)引擎的實(shí)現(xiàn)有關(guān), 在MySQL中使用較多的索引有Hash索引,B+樹索引等,而我們經(jīng)常使用的InnoDB存儲(chǔ)引擎的默認(rèn)索引實(shí)現(xiàn)為:B+樹索引.

3. Hash索引和B+樹所有有什么區(qū)別或者說優(yōu)劣呢?

首先要知道Hash索引和B+樹索引的底層實(shí)現(xiàn)原理:
hash索引底層就是hash表,進(jìn)行查找時(shí),調(diào)用一次hash函數(shù)就可以獲取到相應(yīng)的鍵值,之后進(jìn)行回表查詢獲得實(shí)際數(shù)據(jù).B+樹底層實(shí)現(xiàn)是多路平衡查找樹.
對(duì)于每一次的查詢都是從根節(jié)點(diǎn)出發(fā),查找到葉子節(jié)點(diǎn)方可以獲得所查鍵值,然后根據(jù)查詢判斷是否需要回表查詢數(shù)據(jù).那么可以看出他們有以下的不同:

  • hash索引進(jìn)行等值查詢更快(一般情況下),但是卻無法進(jìn)行范圍查詢.

因?yàn)樵趆ash索引中經(jīng)過hash函數(shù)建立索引之后,索引的順序與原順序無法保持一致,不能支持范圍查詢.而B+樹的的所有節(jié)點(diǎn)皆遵循(左節(jié)點(diǎn)小于父節(jié)點(diǎn),右節(jié)點(diǎn)大于父節(jié)點(diǎn),多叉樹也類似),天然支持范圍.

  • hash索引不支持使用索引進(jìn)行排序,原理同上.

  • hash索引不支持模糊查詢以及多列索引的最左前綴匹配.原理也是因?yàn)閔ash函數(shù)的不可預(yù)測.AAAAAAAAB的索引沒有相關(guān)性.

  • hash索引任何時(shí)候都避免不了回表查詢數(shù)據(jù),而B+樹在符合某些條件(聚簇索引,覆蓋索引等)的時(shí)候可以只通過索引完成查詢.

  • hash索引雖然在等值查詢上較快,但是不穩(wěn)定.性能不可預(yù)測,當(dāng)某個(gè)鍵值存在大量重復(fù)的時(shí)候,發(fā)生hash碰撞,此時(shí)效率可能極差.而B+樹的查詢效率比較穩(wěn)定,對(duì)于所有的查詢都是從根節(jié)點(diǎn)到葉子節(jié)點(diǎn),且樹的高度較低.

因此,在大多數(shù)情況下,直接選擇B+樹索引可以獲得穩(wěn)定且較好的查詢速度.而不需要使用hash索引.

4. 上面提到了B+樹在滿足聚簇索引和覆蓋索引的時(shí)候不需要回表查詢數(shù)據(jù),什么是聚簇索引?

在B+樹的索引中,葉子節(jié)點(diǎn)可能存儲(chǔ)了當(dāng)前的key值,也可能存儲(chǔ)了當(dāng)前的key值以及整行的數(shù)據(jù),這就是聚簇索引和非聚簇索引.
在InnoDB中,只有主鍵索引是聚簇索引,如果沒有主鍵,則挑選一個(gè)唯一鍵建立聚簇索引.如果沒有唯一鍵,則隱式的生成一個(gè)鍵來建立聚簇索引.
當(dāng)查詢使用聚簇索引時(shí),在對(duì)應(yīng)的葉子節(jié)點(diǎn),可以獲取到整行數(shù)據(jù),因此不用再次進(jìn)行回表查詢.

5. 非聚簇索引一定會(huì)回表查詢嗎?

不一定,這涉及到查詢語句所要求的字段是否全部命中了索引,如果全部命中了索引,那么就不必再進(jìn)行回表查詢.
舉個(gè)簡單的例子,假設(shè)我們?cè)趩T工表的年齡上建立了索引,那么當(dāng)進(jìn)行select age from employee where age < 20的查詢時(shí),在索引的葉子節(jié)點(diǎn)上,已經(jīng)包含了age信息,不會(huì)再次進(jìn)行回表查詢.

6. 在建立索引的時(shí)候,都有哪些需要考慮的因素呢?

建立索引的時(shí)候一般要考慮到字段的使用頻率,經(jīng)常作為條件進(jìn)行查詢的字段比較適合.如果需要建立聯(lián)合索引的話,還需要考慮聯(lián)合索引中的順序.
此外也要考慮其他方面,比如防止過多的所有對(duì)表造成太大的壓力.這些都和實(shí)際的表結(jié)構(gòu)以及查詢方式有關(guān).

7. 聯(lián)合索引是什么?為什么需要注意聯(lián)合索引中的順序?

MySQL可以使用多個(gè)字段同時(shí)建立一個(gè)索引,叫做聯(lián)合索引.在聯(lián)合索引中,如果想要命中索引,需要按照建立索引時(shí)的字段順序挨個(gè)使用,否則無法命中索引.
具體原因?yàn)?
MySQL使用索引時(shí)需要索引有序,假設(shè)現(xiàn)在建立了"name,age,school"的聯(lián)合索引
那么索引的排序?yàn)? 先按照name排序,如果name相同,則按照age排序,如果age的值也相等,則按照school進(jìn)行排序.
當(dāng)進(jìn)行查詢時(shí),此時(shí)索引僅僅按照name嚴(yán)格有序,因此必須首先使用name字段進(jìn)行等值查詢,之后對(duì)于匹配到的列而言,其按照age字段嚴(yán)格有序,此時(shí)可以使用age字段用做索引查找,以此類推.
因此在建立聯(lián)合索引的時(shí)候應(yīng)該注意索引列的順序,一般情況下,將查詢需求頻繁或者字段選擇性高的列放在前面.此外可以根據(jù)特例的查詢或者表結(jié)構(gòu)進(jìn)行單獨(dú)的調(diào)整.

8. 創(chuàng)建的索引有沒有被使用到?或者說怎么才可以知道這條語句運(yùn)行很慢的原因?

MySQL提供了explain命令來查看語句的執(zhí)行計(jì)劃,MySQL在執(zhí)行某個(gè)語句之前,會(huì)將該語句過一遍查詢優(yōu)化器,之后會(huì)拿到對(duì)語句的分析,也就是執(zhí)行計(jì)劃,其中包含了許多信息.
可以通過其中和索引有關(guān)的信息來分析是否命中了索引,例如possilbe_key,key,key_len等字段,分別說明了此語句可能會(huì)使用的索引,實(shí)際使用的索引以及使用的索引長度.

9. 那么在哪些情況下會(huì)發(fā)生針對(duì)該列創(chuàng)建了索引但是在查詢的時(shí)候并沒有使用呢?

  • 使用不等于查詢

  • 列參與了數(shù)學(xué)運(yùn)算或者函數(shù)

  • 在字符串like時(shí)左邊是通配符.類似于'%aaa'.

  • 當(dāng)mysql分析全表掃描比使用索引快的時(shí)候不使用索引.

  • 當(dāng)使用聯(lián)合索引,前面一個(gè)條件為范圍查詢,后面的即使符合最左前綴原則,也無法使用索引.

以上情況,MySQL無法使用索引.

事務(wù)相關(guān)

1. 什么是事務(wù)?

理解什么是事務(wù)最經(jīng)典的就是轉(zhuǎn)賬的栗子,相信大家也都了解,這里就不再說一邊了.
事務(wù)是一系列的操作,他們要符合ACID特性.最常見的理解就是:事務(wù)中的操作要么全部成功,要么全部失敗.但是只是這樣還不夠的.

2. ACID是什么?可以詳細(xì)說一下嗎?

A=Atomicity

原子性,就是上面說的,要么全部成功,要么全部失敗.不可能只執(zhí)行一部分操作.

C=Consistency

系統(tǒng)(數(shù)據(jù)庫)總是從一個(gè)一致性的狀態(tài)轉(zhuǎn)移到另一個(gè)一致性的狀態(tài),不會(huì)存在中間狀態(tài).

I=Isolation

隔離性: 通常來說:一個(gè)事務(wù)在完全提交之前,對(duì)其他事務(wù)是不可見的.注意前面的通常來說加了紅色,意味著有例外情況.

D=Durability

持久性,一旦事務(wù)提交,那么就永遠(yuǎn)是這樣子了,哪怕系統(tǒng)崩潰也不會(huì)影響到這個(gè)事務(wù)的結(jié)果.

3. 同時(shí)有多個(gè)事務(wù)在進(jìn)行會(huì)怎么樣呢?

多事務(wù)的并發(fā)進(jìn)行一般會(huì)造成以下幾個(gè)問題:

  • 臟讀: A事務(wù)讀取到了B事務(wù)未提交的內(nèi)容,而B事務(wù)后面進(jìn)行了回滾.

  • 不可重復(fù)讀: 當(dāng)設(shè)置A事務(wù)只能讀取B事務(wù)已經(jīng)提交的部分,會(huì)造成在A事務(wù)內(nèi)的兩次查詢,結(jié)果竟然不一樣,因?yàn)樵诖似陂gB事務(wù)進(jìn)行了提交操作.

  • 幻讀: A事務(wù)讀取了一個(gè)范圍的內(nèi)容,而同時(shí)B事務(wù)在此期間插入了一條數(shù)據(jù).造成"幻覺".

4. 怎么解決這些問題呢?MySQL的事務(wù)隔離級(jí)別了解嗎?MySQL的四種隔離級(jí)別如下:

  • 未提交讀(READ UNCOMMITTED)

這就是上面所說的例外情況了,這個(gè)隔離級(jí)別下,其他事務(wù)可以看到本事務(wù)沒有提交的部分修改.因此會(huì)造成臟讀的問題(讀取到了其他事務(wù)未提交的部分,而之后該事務(wù)進(jìn)行了回滾).這個(gè)級(jí)別的性能沒有足夠大的優(yōu)勢,但是又有很多的問題,因此很少使用.

  • 已提交讀(READ COMMITTED)

其他事務(wù)只能讀取到本事務(wù)已經(jīng)提交的部分.這個(gè)隔離級(jí)別有 不可重復(fù)讀的問題,在同一個(gè)事務(wù)內(nèi)的兩次讀取,拿到的結(jié)果竟然不一樣,因?yàn)榱硗庖粋€(gè)事務(wù)對(duì)數(shù)據(jù)進(jìn)行了修改.

  • REPEATABLE READ(可重復(fù)讀)

可重復(fù)讀隔離級(jí)別解決了上面不可重復(fù)讀的問題(看名字也知道),但是仍然有一個(gè)新問題,就是幻讀當(dāng)你讀取id> 10 的數(shù)據(jù)行時(shí),對(duì)涉及到的所有行加上了讀鎖,此時(shí)例外一個(gè)事務(wù)新插入了一條id=11的數(shù)據(jù),因?yàn)槭切虏迦氲?所以不會(huì)觸發(fā)上面的鎖的排斥那么進(jìn)行本事務(wù)進(jìn)行下一次的查詢時(shí)會(huì)發(fā)現(xiàn)有一條id=11的數(shù)據(jù),而上次的查詢操作并沒有獲取到,再進(jìn)行插入就會(huì)有主鍵沖突的問題.

  • SERIALIZABLE(可串行化)

這是最高的隔離級(jí)別,可以解決上面提到的所有問題,因?yàn)樗麖?qiáng)制將所以的操作串行執(zhí)行,這會(huì)導(dǎo)致并發(fā)性能極速下降,因此也不是很常用.

5. Innodb使用的是哪種隔離級(jí)別呢?

InnoDB默認(rèn)使用的是可重復(fù)讀隔離級(jí)別.

6. 對(duì)MySQL的鎖了解嗎?

當(dāng)數(shù)據(jù)庫有并發(fā)事務(wù)的時(shí)候,可能會(huì)產(chǎn)生數(shù)據(jù)的不一致,這時(shí)候需要一些機(jī)制來保證訪問的次序,鎖機(jī)制就是這樣的一個(gè)機(jī)制.
就像酒店的房間,如果大家隨意進(jìn)出,就會(huì)出現(xiàn)多人搶奪同一個(gè)房間的情況,而在房間上裝上鎖,申請(qǐng)到鑰匙的人才可以入住并且將房間鎖起來,其他人只有等他使用完畢才可以再次使用.

7. MySQL都有哪些鎖呢?像上面那樣子進(jìn)行鎖定豈不是有點(diǎn)阻礙并發(fā)效率了?

從鎖的類別上來講,有共享鎖和排他鎖.
共享鎖: 又叫做讀鎖. 當(dāng)用戶要進(jìn)行數(shù)據(jù)的讀取時(shí),對(duì)數(shù)據(jù)加上共享鎖.共享鎖可以同時(shí)加上多個(gè).
排他鎖: 又叫做寫鎖. 當(dāng)用戶要進(jìn)行數(shù)據(jù)的寫入時(shí),對(duì)數(shù)據(jù)加上排他鎖.排他鎖只可以加一個(gè),他和其他的排他鎖,共享鎖都相斥.
用上面的例子來說就是用戶的行為有兩種,一種是來看房,多個(gè)用戶一起看房是可以接受的. 一種是真正的入住一晚,在這期間,無論是想入住的還是想看房的都不可以.
鎖的粒度取決于具體的存儲(chǔ)引擎,InnoDB實(shí)現(xiàn)了行級(jí)鎖,頁級(jí)鎖,表級(jí)鎖.
他們的加鎖開銷從大大小,并發(fā)能力也是從大到小.

表結(jié)構(gòu)設(shè)計(jì)

1. 為什么要盡量設(shè)定一個(gè)主鍵?

主鍵是數(shù)據(jù)庫確保數(shù)據(jù)行在整張表唯一性的保障,即使業(yè)務(wù)上本張表沒有主鍵,也建議添加一個(gè)自增長的ID列作為主鍵.
設(shè)定了主鍵之后,在后續(xù)的刪改查的時(shí)候可能更加快速以及確保操作數(shù)據(jù)范圍安全.

2. 主鍵使用自增ID還是UUID?

推薦使用自增ID,不要使用UUID.
因?yàn)樵贗nnoDB存儲(chǔ)引擎中,主鍵索引是作為聚簇索引存在的
也就是說,主鍵索引的B+樹葉子節(jié)點(diǎn)上存儲(chǔ)了主鍵索引以及全部的數(shù)據(jù)(按照順序)
如果主鍵索引是自增ID,那么只需要不斷向后排列即可,如果是UUID,由于到來的ID與原來的大小不確定,會(huì)造成非常多的數(shù)據(jù)插入,數(shù)據(jù)移動(dòng),然后導(dǎo)致產(chǎn)生很多的內(nèi)存碎片,進(jìn)而造成插入性能的下降.
總之,在數(shù)據(jù)量大一些的情況下,用自增主鍵性能會(huì)好一些.
圖片來源于《高性能MySQL》: 其中默認(rèn)后綴為使用自增ID,_uuid為使用UUID為主鍵的測試,測試了插入100w行和300w行的性能.

關(guān)于主鍵是聚簇索引,如果沒有主鍵,InnoDB會(huì)選擇一個(gè)唯一鍵來作為聚簇索引,如果沒有唯一鍵,會(huì)生成一個(gè)隱式的主鍵.

If you define a PRIMARY KEY on your table, InnoDB uses it as the clustered index.If you do not define a PRIMARY KEY for your table, MySQL picks the first UNIQUE index that has only NOT NULL columns as the primary key and InnoDB uses it as the clustered index.

3. 字段為什么要求定義為not null?MySQL官網(wǎng)這樣介紹:

NULL columns require additional space in the rowto record whether their values are NULL. For MyISAM tables, each NULL columntakes one bit extra, rounded up to the nearest byte.

null值會(huì)占用更多的字節(jié),且會(huì)在程序中造成很多與預(yù)期不符的情況.

4. 如果要存儲(chǔ)用戶的密碼散列,應(yīng)該使用什么字段進(jìn)行存儲(chǔ)?

密碼散列,鹽,用戶身份證號(hào)等固定長度的字符串應(yīng)該使用char而不是varchar來存儲(chǔ),這樣可以節(jié)省空間且提高檢索效率.

存儲(chǔ)引擎相關(guān)

1. MySQL支持哪些存儲(chǔ)引擎?

MySQL支持多種存儲(chǔ)引擎,比如InnoDB,MyISAM,Memory,Archive等等.在大多數(shù)的情況下,直接選擇使用InnoDB引擎都是最合適的,InnoDB也是MySQL的默認(rèn)存儲(chǔ)引擎.

  1. InnoDB和MyISAM有什么區(qū)別?
  • InnoDB支持事物秩彤,而MyISAM不支持事物

  • InnoDB支持行級(jí)鎖,而MyISAM支持表級(jí)鎖

  • InnoDB支持MVCC, 而MyISAM不支持

  • InnoDB支持外鍵事哭,而MyISAM不支持

  • InnoDB不支持全文索引漫雷,而MyISAM支持。

零散問題

1. MySQL中的varchar和char有什么區(qū)別.

char是一個(gè)定長字段,假如申請(qǐng)了char(10)的空間,那么無論實(shí)際存儲(chǔ)多少內(nèi)容.該字段都占用10個(gè)字符,而varchar是變長的
也就是說申請(qǐng)的只是最大長度,占用的空間為實(shí)際字符長度+1,最后一個(gè)字符存儲(chǔ)使用了多長的空間.
在檢索效率上來講,char > varchar,因此在使用中,如果確定某個(gè)字段的值的長度,可以使用char,否則應(yīng)該盡量使用varchar.例如存儲(chǔ)用戶MD5加密后的密碼,則應(yīng)該使用char.

2. varchar(10)和int(10)代表什么含義?

varchar的10代表了申請(qǐng)的空間長度,也是可以存儲(chǔ)的數(shù)據(jù)的最大長度,而int的10只是代表了展示的長度,不足10位以0填充.
也就是說,int(1)和int(10)所能存儲(chǔ)的數(shù)字大小以及占用的空間都是相同的,只是在展示時(shí)按照長度展示.

3. MySQL的binlog有有幾種錄入格式?分別有什么區(qū)別?

有三種格式,statement,row和mixed.

  • statement模式下,記錄單元為語句.即每一個(gè)sql造成的影響會(huì)記錄.由于sql的執(zhí)行是有上下文的,因此在保存的時(shí)候需要保存相關(guān)的信息,同時(shí)還有一些使用了函數(shù)之類的語句無法被記錄復(fù)制.

  • row級(jí)別下,記錄單元為每一行的改動(dòng),基本是可以全部記下來但是由于很多操作,會(huì)導(dǎo)致大量行的改動(dòng)(比如alter table),因此這種模式的文件保存的信息太多,日志量太大.

  • mixed. 一種折中的方案,普通操作使用statement記錄,當(dāng)無法使用statement的時(shí)候使用row.

此外,新版的MySQL中對(duì)row級(jí)別也做了一些優(yōu)化,當(dāng)表結(jié)構(gòu)發(fā)生變化的時(shí)候,會(huì)記錄語句而不是逐行記錄.

4. 超大分頁怎么處理?

超大的分頁一般從兩個(gè)方向上來解決.

  • 數(shù)據(jù)庫層面,這也是我們主要集中關(guān)注的(雖然收效沒那么大)

    類似于select * from table where age > 20 limit 1000000,10這種查詢其實(shí)也是有可以優(yōu)化的余地的.

    這條語句需要load1000000數(shù)據(jù)然后基本上全部丟棄,只取10條當(dāng)然比較慢.

    我們可以修改為select * from table where id in (select id from table where age > 20 limit 1000000,10)

    這樣雖然也load了一百萬的數(shù)據(jù),但是由于索引覆蓋,要查詢的所有字段都在索引中,所以速度會(huì)很快.

    同時(shí)如果ID連續(xù)的好,我們還可以select * from table where id > 1000000 limit 10,效率也是不錯(cuò)的

    優(yōu)化的可能性有許多種,但是核心思想都一樣,就是減少load的數(shù)據(jù).

  • 從需求的角度減少這種請(qǐng)求….主要是不做類似的需求(直接跳轉(zhuǎn)到幾百萬頁之后的具體某一頁.只允許逐頁查看或者按照給定的路線走,這樣可預(yù)測,可緩存)以及防止ID泄漏且連續(xù)被人惡意攻擊.

解決超大分頁,其實(shí)主要是靠緩存,可預(yù)測性的提前查到內(nèi)容,緩存至redis等k-V數(shù)據(jù)庫中,直接返回即可.在阿里巴巴《Java開發(fā)手冊(cè)》中,對(duì)超大分頁的解決辦法是類似于上面提到的第一種.

5. 關(guān)心過業(yè)務(wù)系統(tǒng)里面的sql耗時(shí)嗎?統(tǒng)計(jì)過慢查詢嗎?對(duì)慢查詢都怎么優(yōu)化過?在業(yè)務(wù)系統(tǒng)中,除了使用主鍵進(jìn)行的查詢,其他的我都會(huì)在測試庫上測試其耗時(shí),慢查詢的統(tǒng)計(jì)主要由運(yùn)維在做,會(huì)定期將業(yè)務(wù)中的慢查詢反饋給我們.慢查詢的優(yōu)化首先要搞明白慢的原因是什么? 是查詢條件沒有命中索引?是load了不需要的數(shù)據(jù)列?還是數(shù)據(jù)量太大?所以優(yōu)化也是針對(duì)這三個(gè)方向來的,

  • 首先分析語句,看看是否load了額外的數(shù)據(jù),可能是查詢了多余的行并且拋棄掉了,可能是加載了許多結(jié)果中并不需要的列,對(duì)語句進(jìn)行分析以及重寫.

  • 分析語句的執(zhí)行計(jì)劃,然后獲得其使用索引的情況,之后修改語句或者修改索引,使得語句可以盡可能的命中索引.

  • 如果對(duì)語句的優(yōu)化已經(jīng)無法進(jìn)行,可以考慮表中的數(shù)據(jù)量是否太大,如果是的話可以進(jìn)行橫向或者縱向的分表.

6. 上面提到橫向分表和縱向分表,可以分別舉一個(gè)適合他們的例子嗎?

橫向分表是按行分表.假設(shè)我們有一張用戶表,主鍵是自增ID且同時(shí)是用戶的ID.數(shù)據(jù)量較大,有1億多條,那么此時(shí)放在一張表里的查詢效果就不太理想.
我們可以根據(jù)主鍵ID進(jìn)行分表,無論是按尾號(hào)分,或者按ID的區(qū)間分都是可以的.
假設(shè)按照尾號(hào)0-99分為100個(gè)表,那么每張表中的數(shù)據(jù)就僅有100w.這時(shí)的查詢效率無疑是可以滿足要求的.
縱向分表是按列分表.假設(shè)我們現(xiàn)在有一張文章表.包含字段id-摘要-內(nèi)容.而系統(tǒng)中的展示形式是刷新出一個(gè)列表,列表中僅包含標(biāo)題和摘要
當(dāng)用戶點(diǎn)擊某篇文章進(jìn)入詳情時(shí)才需要正文內(nèi)容.此時(shí),如果數(shù)據(jù)量大,將內(nèi)容這個(gè)很大且不經(jīng)常使用的列放在一起會(huì)拖慢原表的查詢速度.
我們可以將上面的表分為兩張.id-摘要,id-內(nèi)容.當(dāng)用戶點(diǎn)擊詳情,那主鍵再來取一次內(nèi)容即可.而增加的存儲(chǔ)量只是很小的主鍵字段.代價(jià)很小.
當(dāng)然,分表其實(shí)和業(yè)務(wù)的關(guān)聯(lián)度很高,在分表之前一定要做好調(diào)研以及benchmark.不要按照自己的猜想盲目操作.

7. 什么是存儲(chǔ)過程鳍咱?有哪些優(yōu)缺點(diǎn)降盹?

存儲(chǔ)過程是一些預(yù)編譯的SQL語句。
1流炕、更加直白的理解:存儲(chǔ)過程可以說是一個(gè)記錄集澎现,它是由一些T-SQL語句組成的代碼塊
這些T-SQL語句代碼像一個(gè)方法一樣實(shí)現(xiàn)一些功能(對(duì)單表或多表的增刪改查),然后再給這個(gè)代碼塊取一個(gè)名字每辟,在用到這個(gè)功能的時(shí)候調(diào)用他就行了剑辫。
2、存儲(chǔ)過程是一個(gè)預(yù)編譯的代碼塊渠欺,執(zhí)行效率比較高,一個(gè)存儲(chǔ)過程替代大量T_SQL語句 妹蔽,可以降低網(wǎng)絡(luò)通信量,提高通信速率,可以一定程度上確保數(shù)據(jù)安全
但是,在互聯(lián)網(wǎng)項(xiàng)目中,其實(shí)是不太推薦存儲(chǔ)過程的,比較出名的就是阿里的《Java開發(fā)手冊(cè)》中禁止使用存儲(chǔ)過程
我個(gè)人的理解是,在互聯(lián)網(wǎng)項(xiàng)目中,迭代太快,項(xiàng)目的生命周期也比較短,人員流動(dòng)相比于傳統(tǒng)的項(xiàng)目也更加頻繁
在這樣的情況下,存儲(chǔ)過程的管理確實(shí)是沒有那么方便,同時(shí),復(fù)用性也沒有寫在服務(wù)層那么好.

8. 說一說三個(gè)范式

第一范式: 每個(gè)列都不可以再拆分.
第二范式: 非主鍵列完全依賴于主鍵,而不能是依賴于主鍵的一部分.
第三范式: 非主鍵列只依賴于主鍵,不依賴于其他非主鍵.在設(shè)計(jì)數(shù)據(jù)庫結(jié)構(gòu)的時(shí)候,要盡量遵守三范式,如果不遵守,必須有足夠的理由.比如性能. 事實(shí)上我們經(jīng)常會(huì)為了性能而妥協(xié)數(shù)據(jù)庫的設(shè)計(jì).

9. MyBatis 中的

亂入了一個(gè)奇怪的問題…..我只是想單獨(dú)記錄一下這個(gè)問題,因?yàn)槌霈F(xiàn)頻率太高了.
會(huì)將傳入的內(nèi)容當(dāng)做字符串,而$會(huì)直接將傳入值拼接在sql語句中.
所以#可以在一定程度上預(yù)防sql注入攻擊

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市胳岂,隨后出現(xiàn)的幾起案子编整,更是在濱河造成了極大的恐慌,老刑警劉巖乳丰,帶你破解...
    沈念sama閱讀 216,651評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掌测,死亡現(xiàn)場離奇詭異,居然都是意外死亡产园,警方通過查閱死者的電腦和手機(jī)汞斧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來什燕,“玉大人粘勒,你說我怎么就攤上這事∈杭矗” “怎么了庙睡?”我有些...
    開封第一講書人閱讀 162,931評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長技俐。 經(jīng)常有香客問我乘陪,道長,這世上最難降的妖魔是什么雕擂? 我笑而不...
    開封第一講書人閱讀 58,218評(píng)論 1 292
  • 正文 為了忘掉前任暂刘,我火速辦了婚禮,結(jié)果婚禮上捂刺,老公的妹妹穿的比我還像新娘。我一直安慰自己募寨,他們只是感情好族展,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,234評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拔鹰,像睡著了一般仪缸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上列肢,一...
    開封第一講書人閱讀 51,198評(píng)論 1 299
  • 那天恰画,我揣著相機(jī)與錄音,去河邊找鬼瓷马。 笑死拴还,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的欧聘。 我是一名探鬼主播片林,決...
    沈念sama閱讀 40,084評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了费封?” 一聲冷哼從身側(cè)響起焕妙,我...
    開封第一講書人閱讀 38,926評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎弓摘,沒想到半個(gè)月后焚鹊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,341評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡韧献,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,563評(píng)論 2 333
  • 正文 我和宋清朗相戀三年末患,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片势决。...
    茶點(diǎn)故事閱讀 39,731評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡阻塑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出果复,到底是詐尸還是另有隱情陈莽,我是刑警寧澤,帶...
    沈念sama閱讀 35,430評(píng)論 5 343
  • 正文 年R本政府宣布虽抄,位于F島的核電站走搁,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏迈窟。R本人自食惡果不足惜私植,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,036評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望车酣。 院中可真熱鬧曲稼,春花似錦、人聲如沸湖员。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娘摔。三九已至窄坦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間凳寺,已是汗流浹背鸭津。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肠缨,地道東北人逆趋。 一個(gè)月前我還...
    沈念sama閱讀 47,743評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像晒奕,于是被迫代替她去往敵國和親父泳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子般哼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,629評(píng)論 2 354