面試篇-數(shù)據(jù)庫(kù)

本問(wèn)很多內(nèi)容摘錄和參考自下面的文章,感謝他們的共享:

面經(jīng)整理-Java基礎(chǔ) https://blog.csdn.net/u012294820/article/details/78732771

數(shù)據(jù)庫(kù)分類

sql
1)mysql
2)sqlserver

nosql
1)鍵值對(duì)數(shù)據(jù)庫(kù):redis、memcache
2)列存儲(chǔ)數(shù)據(jù)庫(kù):hbase
3)文檔型數(shù)據(jù)庫(kù):mongdb
4)圖形數(shù)據(jù)庫(kù):graph

查詢優(yōu)化

性能優(yōu)化:

  • 調(diào)整硬件性能
  • 影響因素:
  • 磁盤IO
  • 網(wǎng)絡(luò)IO吞吐量

解決方案:

  • 擴(kuò)大虛擬內(nèi)存,并保證有足夠的可以擴(kuò)充的空間
  • 關(guān)閉數(shù)據(jù)庫(kù)服務(wù)器上不必要的服務(wù)
  • 數(shù)據(jù)庫(kù)服務(wù)器和主域服務(wù)器分開
  • 數(shù)據(jù)庫(kù)服務(wù)器的吞吐量調(diào)為最大
  • 調(diào)整數(shù)據(jù)庫(kù)
  • 只建立一個(gè)聚簇索引
  • 為經(jīng)常查詢的列都建立索引
  • 不要建立太多的索引
  • 避免為大型數(shù)據(jù)類型的列建立索引
  • 使用存儲(chǔ)過(guò)程
  • 盡量使用存儲(chǔ)過(guò)程
  • 應(yīng)用程序結(jié)構(gòu)和算法

索引

索引概念:
索引是對(duì)數(shù)據(jù)庫(kù)表中一個(gè)或多個(gè)列的值進(jìn)行排序的結(jié)構(gòu)

索引的原理:
數(shù)據(jù)庫(kù)索引,是數(shù)據(jù)庫(kù)管理系統(tǒng)中一個(gè)排序的數(shù)據(jù)結(jié)構(gòu),以協(xié)助快速查詢、更新數(shù)據(jù)庫(kù)表中數(shù)據(jù)。索引的實(shí)現(xiàn)通常使用B樹及其變種B+樹。
在數(shù)據(jù)之外,數(shù)據(jù)庫(kù)系統(tǒng)還維護(hù)著滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu),這些數(shù)據(jù)結(jié)構(gòu)以某種方式引用(指向)數(shù)據(jù),這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)上實(shí)現(xiàn)高級(jí)查找算法。這種數(shù)據(jù)結(jié)構(gòu),就是索引。

優(yōu)點(diǎn):
1.大大加快檢索速度;
2.創(chuàng)建唯一性索引,保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性;
3.加速表和表之間的連接;
4.在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時(shí),可以顯著減少查詢中分組和排序的時(shí)間:
(1)大大減少服務(wù)器需要掃描的數(shù)據(jù)量
(2)幫助服務(wù)器避免排序和臨時(shí)表
(3)將所及I/O變?yōu)轫樞騃/O

缺點(diǎn):
1.索引需要占用數(shù)據(jù)表以外的物理存儲(chǔ)空間
2.創(chuàng)建索引和維護(hù)索引要花費(fèi)一定的時(shí)間
3.當(dāng)對(duì)表進(jìn)行更新操作時(shí),索引需要被重建,這樣降低了數(shù)據(jù)的維護(hù)速度。

使用原則:

  1. 不要索引數(shù)據(jù)量不大的表,對(duì)于小表來(lái)講,表掃描的成本并不高。
  2. 不要設(shè)置過(guò)多的索引,在沒(méi)有聚集索引的表中,最大可以設(shè)置249個(gè)非聚集索引,過(guò)多的索引首先會(huì)帶來(lái)更大的磁盤空間,而且在數(shù)據(jù)發(fā)生修改時(shí),對(duì)索引的維護(hù)是特別消耗性能的。所以:一般一張表建立最多5個(gè)索引
  3. 合理應(yīng)用復(fù)合索引,有某些情況下可以考慮創(chuàng)建包含所有輸出列的復(fù)合索引。
  4. 對(duì)經(jīng)常使用范圍查詢的字段,可能考慮聚集索引。
  5. 避免對(duì)不常用的列,邏輯性列,大字段列創(chuàng)建索引。

導(dǎo)致sql不走索引的情況:

  1. 在where查詢條件后面帶有(+、-、*、/、!、<>、%)操作符將會(huì)導(dǎo)致查詢不走索引而而選擇全表查詢
  2. 在where子句中判斷is null,或not in ,not exist
  3. where子句后面用or鏈接,但是一個(gè)字段有索引而另外的字段沒(méi)有索引就會(huì)導(dǎo)致不走索引
  4. 使用like時(shí)如果前面有%也會(huì)導(dǎo)致sql不走索引比如
    SELECT * FROM TB_NAME WHERE uname LIKE'ABC%' -- 走索引
    SELECT * FROM houdunwang WHERE uname LIKE "%ABC%" -- 不走索引
  5. 對(duì)索引列進(jìn)行函數(shù)計(jì)算也會(huì)導(dǎo)致sql不走索引比如
    SELECT TB_NAME FROM stu WHERE age+10=30;
  6. 建立組合索引,但查詢謂詞并未使用組合索引的第一列。
  7. where子句中使用參數(shù),select id from t where num=@num
  8. 類型錯(cuò)誤,字段類型為varchar,where條件用number

參考一:Mysql引起索引失效的原因總結(jié)
參考二:造成數(shù)據(jù)庫(kù)索引失效的幾種原因

索引類型:

普通索引:create index stusno on student(sno),alter table
唯一索引: UNIQUE 例如:create unique index stusno on student(sno);
表明此索引的每一個(gè)索引值只對(duì)應(yīng)唯一的數(shù)據(jù)記錄,對(duì)于單列惟一性索引,這保證單列不包含重復(fù)的值。對(duì)于多列惟一性索引,保證多個(gè)值的組合不重復(fù)。

主鍵索引: primary key
數(shù)據(jù)庫(kù)表經(jīng)常有一列或多列組合,其值唯一標(biāo)識(shí)表中的每一行。該列稱為表的主鍵。在數(shù)據(jù)庫(kù)關(guān)系圖中為表定義主鍵將自動(dòng)創(chuàng)建主鍵索引,主鍵索引是唯一索引的特定類型。該索引要求主鍵中的每個(gè)值都唯一。當(dāng)在查詢中使用主鍵索引時(shí),它還允許對(duì)數(shù)據(jù)的快速訪問(wèn)。

聚集索引:cluster
在聚集索引中,表中行的物理順序與鍵值的邏輯(索引)順序相同。一個(gè)表只能包含一個(gè)聚集索引。 如果某索引不是聚集索引,則表中行的物理順序與鍵值的邏輯順序不匹配。與非聚集索引相比,聚集索引通常提供更快的數(shù)據(jù)訪問(wèn)速度。

全文索引:fulltext

舉例:
CREATE INDEX indextest5 ON textbook (tag5)
ALTER TABLE textbook ADD PRIMARY KEY (timeKey)
ALTER TABLE textbook ADD UNIQUE indextest0 (timeKey)
ALTER TABLE textbook ADD INDEX indextest3 (tag3)
ALTER TABLE textbook ADD FULLTEXT indextest4 (tag4)
ALTER TABLE textbook ADD CLUSTERED indextest6 (tag6)

實(shí)現(xiàn)方式

  1. B+樹
    我們經(jīng)常聽到B+樹就是這個(gè)概念,用這個(gè)樹的目的和紅黑樹差不多,也是為了盡量保持樹的平衡,當(dāng)然紅黑樹是二叉樹,但B+樹就不是二叉樹了,節(jié)點(diǎn)下面可以有多個(gè)子節(jié)點(diǎn),數(shù)據(jù)庫(kù)開發(fā)商會(huì)設(shè)置子節(jié)點(diǎn)數(shù)的一個(gè)最大值,這個(gè)值不會(huì)太小,所以B+樹一般來(lái)說(shuō)比較矮胖,而紅黑樹就比較瘦高了。
    關(guān)于B+樹的插入,刪除,會(huì)涉及到一些算法以保持樹的平衡,這里就不詳述了。ORACLE的默認(rèn)索引就是這種結(jié)構(gòu)的。
    如果經(jīng)常需要同時(shí)對(duì)兩個(gè)字段進(jìn)行AND查詢,那么使用兩個(gè)單獨(dú)索引不如建立一個(gè)復(fù)合索引,因?yàn)閮蓚€(gè)單獨(dú)索引通常數(shù)據(jù)庫(kù)只能使用其中一個(gè),而使用復(fù)合索引因?yàn)樗饕旧砭蛯?duì)應(yīng)到兩個(gè)字段上的,效率會(huì)有很大提高。

  2. 散列索引
    第二種索引叫做散列索引,就是通過(guò)散列函數(shù)來(lái)定位的一種索引,不過(guò)很少有單獨(dú)使用散列索引的,反而是散列文件組織用的比較多。
    散列文件組織就是根據(jù)一個(gè)鍵通過(guò)散列計(jì)算把對(duì)應(yīng)的記錄都放到同一個(gè)槽中,這樣的話相同的鍵值對(duì)應(yīng)的記錄就一定是放在同一個(gè)文件里了,也就減少了文件讀取的次數(shù),提高了效率。
    散列索引呢就是根據(jù)對(duì)應(yīng)鍵的散列碼來(lái)找到最終的索引項(xiàng)的技術(shù),其實(shí)和B樹就差不多了,也就是一種索引之上的二級(jí)輔助索引,我理解散列索引都是二級(jí)或更高級(jí)的稀疏索引,否則桶就太多了,效率也不會(huì)很高。

  3. 位圖索引
    位圖索引是一種針對(duì)多個(gè)字段的簡(jiǎn)單查詢?cè)O(shè)計(jì)的一種特殊的索引,適用范圍比較小,只適用于字段值固定并且值的種類很少的情況,比如性別,只能有男和女,或者級(jí)別,狀態(tài)等等,并且只有在同時(shí)對(duì)多個(gè)這樣的字段查詢時(shí)才能體現(xiàn)出位圖的優(yōu)勢(shì)。
    位圖的基本思想就是對(duì)每一個(gè)條件都用0或者1來(lái)表示,如有5條記錄,性別分別是男,女,男,男,女,那么如果使用位圖索引就會(huì)建立兩個(gè)位圖,對(duì)應(yīng)男的10110和對(duì)應(yīng)女的01001,這樣做有什么好處呢,就是如果同時(shí)對(duì)多個(gè)這種類型的字段進(jìn)行and或or查詢時(shí),可以使用按位與和按位或來(lái)直接得到結(jié)果了。MySQL不支持

三種索引實(shí)現(xiàn)方式的比較

  • B+樹最常用,性能也不差,用于范圍查詢和單值查詢都可以。特別是范圍查詢,非得用B+樹這種順序的才可以了。
  • HASH的如果只是對(duì)單值查詢的話速度會(huì)比B+樹快一點(diǎn),但是ORACLE好像不支持HASH索引,只支持HASH表空間。
  • 位圖的使用情況很局限,只有很少的情況才能用,一定要確定真正適合使用這種索引才用(值的類型很少并且需要復(fù)合查詢,比如性別),否則建立一大堆位圖就一點(diǎn)意義都沒(méi)有了。

B+樹的基本原理?

MySQL是怎么用B+樹?

索引的數(shù)據(jù)結(jié)構(gòu)?

使用索引查詢一定能提高查詢的性能嗎?
通常,通過(guò)索引查詢數(shù)據(jù)比全表掃描要快.但是我們也必須注意到它的代價(jià):

  • 索引需要空間來(lái)存儲(chǔ),也需要定期維護(hù), 每當(dāng)有記錄在表中增減或索引列被修改時(shí),索引本身也會(huì)被修改. 這意味著每條記錄的INSERT,DELETE,UPDATE將為此多付出4,5 次的磁盤I/O. 因?yàn)樗饕枰~外的存儲(chǔ)空間和處理,那些不必要的索引反而會(huì)使查詢反應(yīng)時(shí)間變慢.使用索引查詢不一定能提高查詢性能,索引范圍查詢(INDEX RANGE SCAN)適用于兩種情況:
    基于一個(gè)范圍的檢索 一般查詢返回結(jié)果集小于表中記錄數(shù)的30%
    基于非唯一性索引的檢索 對(duì)于建立索引的列,數(shù)據(jù)是均勻分布好還是不均勻分布好

  • 數(shù)據(jù)均勻分布比較好。最好每條記錄的索引列的值各不相同,比如ID,這樣查找效率最高。比如年齡,對(duì)于千萬(wàn)級(jí)的大表,分布還是太集中了,加上索引也沒(méi)有太大用處。

聚簇索引是怎么存在B+樹里面的?

聚簇索引索引和非聚簇索引的區(qū)別

聚簇索引:
索引順序與表中記錄的物理順序一致
非聚簇索引:
索引順序與表中記錄的物理順序無(wú)關(guān)

參考:聚簇索引與非聚簇索引的區(qū)別

復(fù)合索引
Mysql從左到右的使用索引中的字段,一個(gè)查詢可以只使用索引中的一部份,但只能是最左側(cè)部分。例如索引是key index (a,b,c)。 可以支持a | a,b| a,b,c 3種組合進(jìn)行查找,但不支持 b,c進(jìn)行查找 ,當(dāng)最左側(cè)字段是常量引用時(shí),索引就十分有效。

有三種查詢,1)字段A查詢,2)字段B查詢,3)字段A和字段B復(fù)合查詢,至少需要建立幾個(gè)索引。
三種查詢對(duì)應(yīng)的索引:idx_A,idx_B,idx_A_B

至少2個(gè)索引,如果是按照AB順序的復(fù)合查詢,那么需要idx_B和idx_A_B索引。因?yàn)閺?fù)合idx_A_B只支持A或者AB,不支持B查詢
參考一:mysql數(shù)據(jù)庫(kù)復(fù)合索引

MySQL查詢記錄時(shí),每次只使用一個(gè)索引

原因:

  • MySQL的查詢SQL會(huì)經(jīng)過(guò)查詢優(yōu)化器優(yōu)化,生成執(zhí)行計(jì)劃,再進(jìn)行查詢;
    優(yōu)化過(guò)程中,如果要分析兩個(gè)索引,那么整個(gè)查詢時(shí)間將會(huì)比使用一個(gè)索引進(jìn)行查詢的時(shí)間長(zhǎng);
  • 另一方面,不使用索引直接掃描全表的時(shí)間又比使用一個(gè)索引查詢時(shí)間長(zhǎng),所以MySQL只使用一個(gè)索引;

強(qiáng)制使用指定的索引:
如果有多個(gè)索引,MySQL會(huì)自己選擇使用其中一個(gè),當(dāng)然,我們自己也可以強(qiáng)制讓它使用某一個(gè)索引(select * from table force index(ziduan1_index) limit 2;(強(qiáng)制使用索引"ziduan1_index"))。
參考一:數(shù)據(jù)庫(kù)中查詢記錄時(shí)是否每次只能使用一個(gè)索引?

100個(gè)字段都是經(jīng)常查詢的,如何建索引?是對(duì)這100個(gè)字段,分別建立索引?還是對(duì)這100個(gè)字段,建立復(fù)合索引

分析:

  • 對(duì)于經(jīng)常有INSERT,DELETE,UPDATE的表,索引超過(guò)10個(gè)開銷會(huì)太大,會(huì)影響性能。
  • 一個(gè)表哪怕只做查詢操作,索引也不宜過(guò)多,因?yàn)樗饕鄷?huì)導(dǎo)致查詢選擇索引出現(xiàn)開銷(當(dāng)然指定了索引可以最低限度的降低開銷)。
  • 建立索引要從全局考慮,就是不要只考慮一張表的索引怎么建,而是要考慮整個(gè)模塊的索引怎么建,一般在一個(gè)表上索引不要超過(guò)5個(gè)。

事務(wù)(ACID)

含義:

作為單個(gè)邏輯工作單元執(zhí)行的一系列操作,要么完全地執(zhí)行,要么完全地不執(zhí)行

原則:

原子性(Atomicity):一個(gè)事務(wù)(Transaction)中的所有操作,要么全部完成,要么全部不完成,不會(huì)結(jié)束在中間某個(gè)環(huán)節(jié)。事務(wù)在執(zhí)行過(guò)程中發(fā)生錯(cuò)誤,會(huì)被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個(gè)事務(wù)從來(lái)沒(méi)有執(zhí)行過(guò)一樣。

一致性(Consistency): 在事務(wù)開始之前和事務(wù)結(jié)束以后,數(shù)據(jù)庫(kù)的完整性沒(méi)有被破壞。這表示寫入的資料必須完全符合所有的默認(rèn)規(guī)則,這包含資料的精準(zhǔn)度、串聯(lián)新以及后續(xù)數(shù)據(jù)庫(kù)可以自發(fā)性地完成預(yù)定的工作。A轉(zhuǎn)賬給B,執(zhí)行事務(wù)之前:A+B=100,執(zhí)行事務(wù)之后:A+B=100

隔離性(Isolation): 當(dāng)兩個(gè)或者多個(gè)事務(wù)并發(fā)訪問(wèn)(此處訪問(wèn)指查詢和修改的操作)數(shù)據(jù)庫(kù)的同一數(shù)據(jù)時(shí)所表現(xiàn)出的互相關(guān)系。事務(wù)隔離分為不同的級(jí)別,包括讀不提交(Read uncommitted)、讀提交(Read committed)、可重復(fù)讀(Repeatable read)和串行化(Serializable)。多個(gè)事務(wù)并發(fā)訪問(wèn)相互之間不影響,A事務(wù)的結(jié)果不會(huì)覆蓋B事務(wù)的結(jié)果

持久性(Durability): 在事務(wù)完成以后,該事務(wù)對(duì)數(shù)據(jù)庫(kù)所作的更改便持久地保存在數(shù)據(jù)庫(kù)之中,而且是完全的。事務(wù)一旦提交,對(duì)數(shù)據(jù)庫(kù)數(shù)據(jù)的改變就是永久性的

由于一項(xiàng)操作通常會(huì)包含許多子操作,而這些子操作可能會(huì)因?yàn)橛布膿p壞或其他因素產(chǎn)生問(wèn)題,要正確實(shí)現(xiàn)ACID并不容易。ACID建議數(shù)據(jù)庫(kù)將所有需要更新以及修改的資料一次操作完畢,但實(shí)際上并不可行。

目前主要有兩種方式實(shí)現(xiàn)ACID:

第一種是Write ahead logging,也就是日志式的方式。
第二種是Shadow paging。

Write ahead logging(預(yù)寫日志):

  1. 事務(wù)所引起的所有改動(dòng)都要記錄在日志中,在事務(wù)提交完成之前,所有的這些記錄必須被寫入硬盤;
  2. 一個(gè)數(shù)據(jù)庫(kù)的緩沖頁(yè)直到被記入日志后才能發(fā)生修改。直到緩沖頁(yè)對(duì)應(yīng)的日志被寫入硬盤后,該緩沖頁(yè)才會(huì)存入硬盤;
  3. 當(dāng)緩沖頁(yè)被修改和日志被更新修改時(shí),必須加上互斥鎖,以保證改動(dòng)被記錄到日志中的順序與它發(fā)生的順序是一致的。

以上規(guī)則的結(jié)果:
如果一條日志記錄未被存入硬盤,則它可以被忽略,因?yàn)樵撊罩局邪母膭?dòng)一定屬于未提交的事務(wù)。此外,這樣的日志不能反映已持久化在數(shù)據(jù)庫(kù)中的改動(dòng);
日志記錄按順序記錄系統(tǒng)的改動(dòng)。加鎖協(xié)議(latch protocol)保證如果有對(duì)于同一頁(yè)改動(dòng)的兩條日志記錄,則兩條記錄的順序反映對(duì)頁(yè)發(fā)生改變的順序。

事務(wù)隔離級(jí)別

  • 讀未提交(Read uncommitted): 允許讀取還未提交的改變了的數(shù)據(jù)。可能導(dǎo)致臟、幻、不可重復(fù)讀。
    讀已提交(Read committed) 允許在并發(fā)事務(wù)已經(jīng)提交后讀取。可防止臟讀,但是幻讀和不可重復(fù)讀仍可發(fā)生。
  • 可重復(fù)讀(Repeatable read): 對(duì)相同字段的多次讀取是一致的,除非數(shù)據(jù)被事務(wù)本身改變。可防止臟、不可重復(fù)讀,但是幻讀仍可能發(fā)生。這個(gè)是MySQL的的默認(rèn)事務(wù)隔離級(jí)別
  • 串行化(Serializable): 完全服從數(shù)據(jù)庫(kù)四種隔離級(jí)別,確保不發(fā)生臟、幻、不可重復(fù)讀。速度最慢,它是通過(guò)完全鎖定在事務(wù)中涉及的數(shù)據(jù)表來(lái)完成的,事務(wù)按順序串行執(zhí)行。

不考慮隔離性,會(huì)引發(fā)一下問(wèn)題:

  • 臟讀: 一個(gè)事務(wù)讀取了另一個(gè)事務(wù)改寫但還未提交的數(shù)據(jù),如果這些數(shù)據(jù)被回滾,則讀到的數(shù)據(jù)是無(wú)效的。讀到無(wú)效數(shù)據(jù),導(dǎo)致查詢結(jié)果前后不一致。

  • 不可重復(fù)讀: 在同一個(gè)事務(wù)中,讀到另一個(gè)事務(wù)已經(jīng)提交更新的數(shù)據(jù)。讀到更新的數(shù)據(jù),導(dǎo)致多次讀取同一個(gè)數(shù)據(jù)返回的結(jié)果有所不同。ORACLE默認(rèn)是這個(gè)級(jí)別。

  • 幻讀: 一個(gè)事務(wù)讀取了幾行記錄后,另一個(gè)事務(wù)插入一些記錄,幻讀就發(fā)生了。在后來(lái)的查詢中,第一個(gè)事務(wù)就會(huì)發(fā)現(xiàn)有些原來(lái)沒(méi)有的記錄。讀取到新的記錄

關(guān)系型數(shù)據(jù)庫(kù)的范式

第一范式: 每個(gè)屬性不可再分
第二范式: 消除部分依賴,滿足第一范式,表中的非主屬性必須完全依賴于主鍵(全部主屬性)
第三范式: 消除傳遞依賴,滿足第二范式,非主屬性必須互不依賴

視圖

視圖是一種虛擬的表,具有和物理表相同的功能。可以對(duì)視圖進(jìn)行增,改,查,操作,試圖通常是有一個(gè)表或者多個(gè)表的行或列的子集。對(duì)視圖的修改不影響基本表。它使得我們獲取數(shù)據(jù)更容易,相比多表查詢。

只暴露部分字段給訪問(wèn)者,所以就建一個(gè)虛表,就是視圖。

查詢的數(shù)據(jù)來(lái)源于不同的表,而查詢者希望以統(tǒng)一的方式查詢,這樣也可以建立一個(gè)視圖,把多個(gè)表查詢結(jié)果聯(lián)合起來(lái),查詢者只需要直接從視圖中獲取數(shù)據(jù),不必考慮數(shù)據(jù)來(lái)源于不同表所帶來(lái)的差異

SQL

從表TABLE_NAME中提取10條記錄
sql server:
select top 10 * from TABLE_NAME;

-- mysql:
select * from TABLE_NAME limit 10;

drop、delete與truncate的區(qū)別

SQL中的drop、delete、truncate都表示刪除,但是三者有一些差別:

  • delete和truncate只刪除表的數(shù)據(jù)不刪除表的結(jié)構(gòu).
    速度: 一般來(lái)說(shuō): drop> truncate >delete
  • delete語(yǔ)句是dml,這個(gè)操作會(huì)放到rollback segement中,事務(wù)提交之后才生效;
  • 如果有相應(yīng)的trigger,執(zhí)行的時(shí)候?qū)⒈挥|發(fā). truncate,drop是ddl, 操作立即生效,原數(shù)據(jù)不放到rollback segment中,不能回滾. 操作不觸發(fā)trigger.

drop、delete與truncate分別在什么場(chǎng)景之下使用?

  • 不再需要一張表的時(shí)候,用drop
  • 想刪除部分?jǐn)?shù)據(jù)行時(shí)候,用delete,并且?guī)蟱here子句
    保留表而刪除所有數(shù)據(jù)的時(shí)候用truncate

SQL 約束有哪幾種?

  • NOT NULL: 用于控制字段的內(nèi)容一定不能為空(NULL)。
  • UNIQUE: 控件字段內(nèi)容不能重復(fù),一個(gè)表允許有多個(gè) Unique 約束。
  • PRIMARY KEY: 也是用于控件字段內(nèi)容不能重復(fù),但它在一個(gè)表只允許出現(xiàn)一個(gè)。
  • FOREIGN KEY: 用于預(yù)防破壞表之間連接的動(dòng)作,也能防止非法數(shù)據(jù)插入外鍵列,因?yàn)樗仨毷撬赶虻哪莻€(gè)表中的值之一。
  • CHECK: 用于控制字段的值范圍。
  • DEFAULT: 用于設(shè)置新記錄的默認(rèn)值。

sql注入,如何避免

  • sql注入:用戶輸入的數(shù)據(jù),未經(jīng)檢測(cè),變成了sql語(yǔ)句的一部分,造成意外的結(jié)果輸出。
  • 避免sql注入:避免數(shù)據(jù)變成代碼被執(zhí)行,對(duì)sql語(yǔ)句進(jìn)行預(yù)編譯和查詢參數(shù)綁定,在SQL語(yǔ)句中放置占位符'?',然后將帶有占位符的SQL語(yǔ)句傳給數(shù)據(jù)庫(kù)編譯,執(zhí)行的時(shí)候才將用戶輸入的數(shù)據(jù)作為執(zhí)行的參數(shù)傳給用戶。這樣的操作不僅使得SQL語(yǔ)句在書寫的時(shí)候不再需要拼接,看起來(lái)也更直接,而且用戶輸入的數(shù)據(jù)也沒(méi)有機(jī)會(huì)被送到數(shù)據(jù)庫(kù)的SQL解釋器被編譯執(zhí)行,也不會(huì)越權(quán)變成代碼。
    實(shí)例:登錄界面用戶名輸入:admin' or 1=1 '

主鍵、外鍵、候選鍵、超鍵

  • 超鍵:在關(guān)系中能唯一標(biāo)識(shí)元組的屬性集稱為關(guān)系模式的超鍵。一個(gè)屬- 性可以為作為一個(gè)超鍵,多個(gè)屬性組合在一起也可以作為一個(gè)超鍵。超- 鍵包含候選鍵和主鍵。
  • 候選鍵:是最小超鍵,即沒(méi)有冗余元素的超鍵。
  • 主鍵:數(shù)據(jù)庫(kù)表中對(duì)儲(chǔ)存數(shù)據(jù)對(duì)象予以唯一和完整標(biāo)識(shí)的數(shù)據(jù)列或?qū)傩缘慕M合。一個(gè)數(shù)據(jù)列只能有一個(gè)主鍵,且主鍵的取值不能缺失,即不能為空值(Null)。
  • 外鍵:在一個(gè)表中存在的另一個(gè)表的主鍵稱此表的外鍵。

MySQL的常用引擎

MySQL數(shù)據(jù)庫(kù)中,常用的引擎主要就是2個(gè):Innodb和MyIASM。這篇文章將主要介紹這兩個(gè)引擎,以及該如何去選擇引擎,最后在提一下這2種引擎所使用的數(shù)據(jù)結(jié)構(gòu)是什么。

Innodb引擎。

Innodb引擎提供了對(duì)數(shù)據(jù)庫(kù)ACID事務(wù)的支持。并且還提供了行級(jí)鎖和外鍵的約束。它的設(shè)計(jì)的目標(biāo)就是處理大數(shù)據(jù)容量的數(shù)據(jù)庫(kù)系統(tǒng)。它本身實(shí)際上是基于Mysql后臺(tái)的完整的系統(tǒng)。Mysql運(yùn)行的時(shí)候,Innodb會(huì)在內(nèi)存中建立緩沖池,用于緩沖數(shù)據(jù)和索引。但是,該引擎是不支持全文搜索的。同時(shí),啟動(dòng)也比較的慢,它是不會(huì)保存表的行數(shù)的。當(dāng)進(jìn)行Select count(*) from table指令的時(shí)候,需要進(jìn)行掃描全表。
所以當(dāng)需要使用數(shù)據(jù)庫(kù)的事務(wù)時(shí),該引擎就是首選。由于鎖的粒度小,寫操作是不會(huì)鎖定全表的。所以在并發(fā)度較高的場(chǎng)景下使用會(huì)提升效率的。

MyIASM引擎

mysql5.5之前,它是MySql的默認(rèn)引擎,5.5開始默認(rèn)引擎是Innodb,但不提供事務(wù)的支持,也不支持行級(jí)鎖和外鍵。因此當(dāng)執(zhí)行Insert插入和Update更新語(yǔ)句時(shí),即執(zhí)行寫操作的時(shí)候需要鎖定這個(gè)表。所以會(huì)導(dǎo)致效率會(huì)降低。不過(guò)和Innodb不同的是,MyIASM引擎是保存了表的行數(shù),于是當(dāng)進(jìn)行Select count(*) from table語(yǔ)句時(shí),可以直接的讀取已經(jīng)保存的值而不需要進(jìn)行掃描全表。

所以,如果表的讀操作遠(yuǎn)遠(yuǎn)多于寫操作時(shí),并且不需要事務(wù)的支持的。可以將MyIASM作為數(shù)據(jù)庫(kù)引擎的首先。

這兩種引擎的選擇。其實(shí)上面已經(jīng)提到了。這里我在補(bǔ)充了兩點(diǎn):

  1. 大容量的數(shù)據(jù)集時(shí)趨向于選擇Innodb。因?yàn)樗С质聞?wù)處理和故障的恢復(fù)。Innodb可以利用數(shù)據(jù)日志來(lái)進(jìn)行數(shù)據(jù)的恢復(fù)。主鍵的查詢?cè)贗nnodb也是比較快的。
  2. 大批量的插入語(yǔ)句時(shí)(這里是INSERT語(yǔ)句)在MyIASM引擎中執(zhí)行的比較的快,但是UPDATE語(yǔ)句在Innodb下執(zhí)行的會(huì)比較的快,尤其是在并發(fā)量大的時(shí)候。

兩種引擎所使用的索引的數(shù)據(jù)結(jié)構(gòu)是什么?

答案是都是B+樹。

  • 對(duì)于MyIASM引擎來(lái)說(shuō),B+樹的數(shù)據(jù)結(jié)構(gòu)中存儲(chǔ)的內(nèi)容實(shí)際上是實(shí)際數(shù)據(jù)的地址值。也就是說(shuō)它的索引和實(shí)際數(shù)據(jù)是分開的,只不過(guò)使用索引指向了實(shí)際數(shù)據(jù)。這種索引的模式被稱為非聚集索引。
  • Innodb引擎的索引的數(shù)據(jù)結(jié)構(gòu)也是B+樹,只不過(guò)數(shù)據(jù)結(jié)構(gòu)中存儲(chǔ)的都是實(shí)際的數(shù)據(jù),這種索引有被稱為聚集索引。

mysql一般用的什么數(shù)據(jù)庫(kù)引擎

mysql5.5以后默認(rèn)的是InnoDB存儲(chǔ)引擎

InnoDB和MyISAM之間的區(qū)別、應(yīng)用場(chǎng)景

區(qū)別:
  1. MyISAM不支持事務(wù),InnoDB是事務(wù)類型的存儲(chǔ)引擎
  2. MyISAM只支持表級(jí)鎖,BDB支持頁(yè)級(jí)鎖和表級(jí)鎖默認(rèn)為頁(yè)級(jí)鎖,而InnoDB支持行級(jí)鎖和表級(jí)鎖默認(rèn)為行級(jí)鎖
  3. MyISAM引擎不支持外鍵,InnoDB支持外鍵
  4. MyISAM引擎的表在大量高并發(fā)的讀寫下會(huì)經(jīng)常出現(xiàn)表?yè)p壞的情況
  5. 對(duì)于count()查詢來(lái)說(shuō)MyISAM更有優(yōu)勢(shì)
  6. InnoDB是為處理巨大數(shù)據(jù)量時(shí)的最大性能設(shè)計(jì),它的CPU效率可能是任何其它基于磁盤的關(guān)系數(shù)據(jù)庫(kù)引擎所不能匹敵的
  7. MyISAM支持全文索引(FULLTEXT),InnoDB不支持
  8. MyISAM引擎的表的查詢、更新、插入的效率要比InnoDB高
應(yīng)用場(chǎng)景:

MyISAM:(1)做很多count 的計(jì)算;(2)插入不頻繁,查詢非常頻繁;(3)沒(méi)有事務(wù)。
InnoDB:(1)可靠性要求比較高,或者要求事務(wù);(2)表更新和查詢都相當(dāng)?shù)念l繁,并且行鎖定的機(jī)會(huì)比較大的情況。

數(shù)據(jù)庫(kù)連接

通過(guò)JDBC訪問(wèn)數(shù)據(jù)庫(kù)包含下面哪幾步?

  1. 加載JDBC驅(qū)動(dòng)程序
  2. 提供JDBC連接的URL
  3. 創(chuàng)建數(shù)據(jù)庫(kù)的連接
  4. 創(chuàng)建一個(gè)Statement
  5. 執(zhí)行SQL語(yǔ)句
  6. 處理結(jié)果
  7. 關(guān)閉JDBC對(duì)象

存儲(chǔ)過(guò)程

  • 存儲(chǔ)過(guò)程是一個(gè)預(yù)編譯的代碼塊,執(zhí)行效率比較高
  • 一個(gè)存儲(chǔ)過(guò)程替代大量T_SQL語(yǔ)句 ,可以降低網(wǎng)絡(luò)通信量,提高通信速率
    -- 可以一定程度上確保數(shù)據(jù)安全

觸發(fā)器的作用

觸發(fā)器是一種特殊的存儲(chǔ)過(guò)程,主要是通過(guò)事件來(lái)觸發(fā)而被執(zhí)行的。它可以強(qiáng)化約束,來(lái)維護(hù)數(shù)據(jù)的完整性和一致性,可以跟蹤數(shù)據(jù)庫(kù)內(nèi)的操作從而不允許未經(jīng)許可的更新和變化。可以聯(lián)級(jí)運(yùn)算。如,某表上的觸發(fā)器上包含對(duì)另一個(gè)表的數(shù)據(jù)操作,而該操作又會(huì)導(dǎo)致該表觸發(fā)器被觸發(fā)。

數(shù)據(jù)庫(kù)的樂(lè)觀鎖和悲觀鎖

數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中的并發(fā)控制的任務(wù)是確保在多個(gè)事務(wù)同時(shí)存取數(shù)據(jù)庫(kù)中同一數(shù)據(jù)時(shí)不破壞事務(wù)的隔離性和統(tǒng)一性以及數(shù)據(jù)庫(kù)的統(tǒng)一性。

樂(lè)觀并發(fā)控制(樂(lè)觀鎖)和悲觀并發(fā)控制(悲觀鎖)是并發(fā)控制主要采用的技術(shù)手段。

  • 悲觀鎖:假定會(huì)發(fā)生并發(fā)沖突,屏蔽一切可能違反數(shù)據(jù)完整性的操作
  • 樂(lè)觀鎖:假設(shè)不會(huì)發(fā)生并發(fā)沖突,只在提交操作時(shí)檢查是否違反數(shù)據(jù)完整性。

悲觀鎖和樂(lè)觀鎖的區(qū)別以及應(yīng)用場(chǎng)景

區(qū)別:

  • 悲觀鎖: 每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人會(huì)修改,所以每次在拿數(shù)據(jù)的時(shí)候都會(huì)上鎖,這樣別人想拿這個(gè)數(shù)據(jù)就會(huì)block直到它拿到鎖。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)里邊就用到了很多這種鎖機(jī)制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。比較適合寫入操作比較頻繁的場(chǎng)景,如果出現(xiàn)大量的讀取操作,每次讀取的時(shí)候都會(huì)進(jìn)行加鎖,這樣會(huì)增加大量的鎖的開銷,降低了系統(tǒng)的吞吐量。
  • 樂(lè)觀鎖: 每次去拿數(shù)據(jù)的時(shí)候都認(rèn)為別人不會(huì)修改,所以不會(huì)上鎖,但是在更新的時(shí)候會(huì)判斷一下在此期間別人有沒(méi)有去更新這個(gè)數(shù)據(jù),可以使用版本號(hào)等機(jī)制。樂(lè)觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量,像數(shù)據(jù)庫(kù)如果提供類似于write_condition機(jī)制的其實(shí)都是提供的樂(lè)觀鎖。比較適合讀取操作比較頻繁的場(chǎng)景,如果出現(xiàn)大量的寫入操作,數(shù)據(jù)發(fā)生沖突的可能性就會(huì)增大,為了保證數(shù)據(jù)的一致性,應(yīng)用層需要不斷的重新獲取數(shù)據(jù),這樣會(huì)增加大量的查詢操作,降低了系統(tǒng)的吞吐量。

應(yīng)用場(chǎng)景: 讀取頻繁使用樂(lè)觀鎖,寫入頻繁使用悲觀鎖。

MySQL分表、分區(qū)、分庫(kù)

  • 分表:將一張表分成多個(gè)小表。
  • 分區(qū):一張表的數(shù)據(jù)分成多個(gè)區(qū)塊,這些區(qū)塊可以在同一個(gè)磁盤上,也可以在不同的磁盤上。
  • 分庫(kù):一個(gè)數(shù)據(jù)庫(kù)按城市(或者其他標(biāo)準(zhǔn))分成多個(gè)數(shù)據(jù)庫(kù)。
    參考一:MYSQL分庫(kù)分表總結(jié)

連表查詢:笛卡爾積通過(guò)什么連接得到sql

select * from a, b

inner join,left join,right join的區(qū)別

Table A TableB

aid adate bid bdate

1 a1 1 b1

2 a2 2 b2

3 a3 4 b4

select * from a inner join b on a.aid = b.bid

僅取出匹配的數(shù)據(jù),結(jié)果:

1 a1 b1

2 a2 b2

select * from a left join b on a.aid = b.bid

首先取出a表中所有數(shù)據(jù),然后再加上與a,b匹配的的數(shù)據(jù),結(jié)果::

1 a1 b1

2 a2 b2

3 a3 空字符

select * from a right join b on a.aid = b.bid

指的是首先取出b表中所有數(shù)據(jù),然后再加上與a,b匹配的的數(shù)據(jù),結(jié)果:

1 a1 b1

2 a2 b2

4 空字符 b4

有全字段重復(fù)數(shù)據(jù)怎么去重,寫sql語(yǔ)句:

delete from vitae a

where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)

and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)

數(shù)據(jù)庫(kù)中某個(gè)表查詢和存取數(shù)據(jù)量很大時(shí)怎么處理

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

SQL語(yǔ)句:

Java代碼:

參考一:在一個(gè)千萬(wàn)級(jí)的數(shù)據(jù)庫(kù)查尋中,如何提高查詢效率?

做項(xiàng)目時(shí)怎么設(shè)計(jì)數(shù)據(jù)庫(kù),怎么決定主鍵

因?yàn)槲易约赫劦接眠^(guò)redis,所以又問(wèn)了我redis的原理和優(yōu)勢(shì)

數(shù)據(jù)庫(kù)的底層設(shè)計(jì),文件如何存儲(chǔ),數(shù)據(jù)如何查詢

MongoDB和MySQL的區(qū)別

MongoDB:日志

存儲(chǔ)方式:虛擬內(nèi)存+持久化。

查詢語(yǔ)句:是獨(dú)特的Mongodb的查詢方式。

適合場(chǎng)景:事件的記錄,內(nèi)容管理或者博客平臺(tái)等等。

架構(gòu)特點(diǎn):可以通過(guò)副本集,以及分片來(lái)實(shí)現(xiàn)高可用。

數(shù)據(jù)處理:數(shù)據(jù)是存儲(chǔ)在硬盤上的,只不過(guò)需要經(jīng)常讀取的數(shù)據(jù)會(huì)被加載到內(nèi)存中,將數(shù)據(jù)存儲(chǔ)在物理內(nèi)存中,從而達(dá)到高速讀寫。

不支持事務(wù)

參考一:數(shù)據(jù)庫(kù)-面試題(持續(xù)更新)

參考二:http://www.cnblogs.com/remember-forget/p/6140112.html

參考三:mysql數(shù)據(jù)庫(kù)面試總結(jié)

參考四:數(shù)據(jù)庫(kù)面試寶典

參考五:SQL經(jīng)典面試題及答案

參考六:SQL經(jīng)典面試題目總結(jié)

參考七:15個(gè) MySQL 基礎(chǔ)面試題,DBA 們準(zhǔn)備好了嗎?

參考八:MySQL索引使用方法和性能優(yōu)化

參考九:和剛?cè)腴T的菜鳥們聊聊--什么是聚簇索引與非聚簇索引

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容