本問很多內(nèi)容摘錄和參考自下面的文章,感謝他們的共享:
面經(jīng)整理-Java基礎(chǔ) https://blog.csdn.net/u012294820/article/details/78732771
數(shù)據(jù)庫分類
sql
1)mysql
2)sqlserver
nosql
1)鍵值對數(shù)據(jù)庫:redis、memcache
2)列存儲數(shù)據(jù)庫:hbase
3)文檔型數(shù)據(jù)庫:mongdb
4)圖形數(shù)據(jù)庫:graph
查詢優(yōu)化
性能優(yōu)化:
- 調(diào)整硬件性能
- 影響因素:
- 磁盤IO
- 網(wǎng)絡(luò)IO吞吐量
解決方案:
- 擴大虛擬內(nèi)存记劈,并保證有足夠的可以擴充的空間
- 關(guān)閉數(shù)據(jù)庫服務(wù)器上不必要的服務(wù)
- 數(shù)據(jù)庫服務(wù)器和主域服務(wù)器分開
- 數(shù)據(jù)庫服務(wù)器的吞吐量調(diào)為最大
- 調(diào)整數(shù)據(jù)庫
- 只建立一個聚簇索引
- 為經(jīng)常查詢的列都建立索引
- 不要建立太多的索引
- 避免為大型數(shù)據(jù)類型的列建立索引
- 使用存儲過程
- 盡量使用存儲過程
- 應(yīng)用程序結(jié)構(gòu)和算法
索引
索引概念:
索引是對數(shù)據(jù)庫表中一個或多個列的值進(jìn)行排序的結(jié)構(gòu)
索引的原理:
數(shù)據(jù)庫索引,是數(shù)據(jù)庫管理系統(tǒng)中一個排序的數(shù)據(jù)結(jié)構(gòu)丽焊,以協(xié)助快速查詢余耽、更新數(shù)據(jù)庫表中數(shù)據(jù)。索引的實現(xiàn)通常使用B樹及其變種B+樹砾肺。
在數(shù)據(jù)之外,數(shù)據(jù)庫系統(tǒng)還維護(hù)著滿足特定查找算法的數(shù)據(jù)結(jié)構(gòu)防嗡,這些數(shù)據(jù)結(jié)構(gòu)以某種方式引用(指向)數(shù)據(jù)变汪,這樣就可以在這些數(shù)據(jù)結(jié)構(gòu)上實現(xiàn)高級查找算法。這種數(shù)據(jù)結(jié)構(gòu)蚁趁,就是索引裙盾。
優(yōu)點:
1.大大加快檢索速度;
2.創(chuàng)建唯一性索引,保證數(shù)據(jù)庫表中每一行數(shù)據(jù)的唯一性;
3.加速表和表之間的連接;
4.在使用分組和排序子句進(jìn)行數(shù)據(jù)檢索時他嫡,可以顯著減少查詢中分組和排序的時間:
(1)大大減少服務(wù)器需要掃描的數(shù)據(jù)量
(2)幫助服務(wù)器避免排序和臨時表
(3)將所及I/O變?yōu)轫樞騃/O
缺點:
1.索引需要占用數(shù)據(jù)表以外的物理存儲空間
2.創(chuàng)建索引和維護(hù)索引要花費一定的時間
3.當(dāng)對表進(jìn)行更新操作時番官,索引需要被重建,這樣降低了數(shù)據(jù)的維護(hù)速度钢属。
使用原則:
- 不要索引數(shù)據(jù)量不大的表徘熔,對于小表來講,表掃描的成本并不高淆党。
- 不要設(shè)置過多的索引酷师,在沒有聚集索引的表中讶凉,最大可以設(shè)置249個非聚集索引,過多的索引首先會帶來更大的磁盤空間窒升,而且在數(shù)據(jù)發(fā)生修改時缀遍,對索引的維護(hù)是特別消耗性能的。所以:一般一張表建立最多5個索引
- 合理應(yīng)用復(fù)合索引饱须,有某些情況下可以考慮創(chuàng)建包含所有輸出列的復(fù)合索引域醇。
- 對經(jīng)常使用范圍查詢的字段,可能考慮聚集索引蓉媳。
- 避免對不常用的列譬挚,邏輯性列,大字段列創(chuàng)建索引酪呻。
導(dǎo)致sql不走索引的情況:
- 在where查詢條件后面帶有(+减宣、-、*玩荠、/漆腌、!阶冈、<>闷尿、%)操作符將會導(dǎo)致查詢不走索引而而選擇全表查詢
- 在where子句中判斷is null,或not in 女坑,not exist
- where子句后面用or鏈接填具,但是一個字段有索引而另外的字段沒有索引就會導(dǎo)致不走索引
- 使用like時如果前面有%也會導(dǎo)致sql不走索引比如
SELECT * FROM TB_NAME WHEREuname
LIKE'ABC%' -- 走索引
SELECT * FROMhoudunwang
WHEREuname
LIKE "%ABC%" -- 不走索引 - 對索引列進(jìn)行函數(shù)計算也會導(dǎo)致sql不走索引比如
SELECT TB_NAME FROMstu
WHEREage
+10=30; - 建立組合索引,但查詢謂詞并未使用組合索引的第一列匆骗。
- where子句中使用參數(shù)劳景,select id from t where num=@num
- 類型錯誤,字段類型為varchar碉就,where條件用number
參考一:Mysql引起索引失效的原因總結(jié)
參考二:造成數(shù)據(jù)庫索引失效的幾種原因
索引類型:
普通索引:create index stusno on student(sno)盟广,alter table
唯一索引: UNIQUE 例如:create unique index stusno on student(sno);
表明此索引的每一個索引值只對應(yīng)唯一的數(shù)據(jù)記錄,對于單列惟一性索引瓮钥,這保證單列不包含重復(fù)的值筋量。對于多列惟一性索引,保證多個值的組合不重復(fù)骏庸。
主鍵索引: primary key
數(shù)據(jù)庫表經(jīng)常有一列或多列組合,其值唯一標(biāo)識表中的每一行年叮。該列稱為表的主鍵具被。在數(shù)據(jù)庫關(guān)系圖中為表定義主鍵將自動創(chuàng)建主鍵索引,主鍵索引是唯一索引的特定類型只损。該索引要求主鍵中的每個值都唯一一姿。當(dāng)在查詢中使用主鍵索引時七咧,它還允許對數(shù)據(jù)的快速訪問。
聚集索引:cluster
在聚集索引中叮叹,表中行的物理順序與鍵值的邏輯(索引)順序相同艾栋。一個表只能包含一個聚集索引。 如果某索引不是聚集索引蛉顽,則表中行的物理順序與鍵值的邏輯順序不匹配蝗砾。與非聚集索引相比,聚集索引通常提供更快的數(shù)據(jù)訪問速度携冤。
全文索引: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)
實現(xiàn)方式
B+樹
我們經(jīng)常聽到B+樹就是這個概念悼粮,用這個樹的目的和紅黑樹差不多,也是為了盡量保持樹的平衡曾棕,當(dāng)然紅黑樹是二叉樹扣猫,但B+樹就不是二叉樹了,節(jié)點下面可以有多個子節(jié)點翘地,數(shù)據(jù)庫開發(fā)商會設(shè)置子節(jié)點數(shù)的一個最大值申尤,這個值不會太小,所以B+樹一般來說比較矮胖衙耕,而紅黑樹就比較瘦高了昧穿。
關(guān)于B+樹的插入,刪除臭杰,會涉及到一些算法以保持樹的平衡粤咪,這里就不詳述了。ORACLE的默認(rèn)索引就是這種結(jié)構(gòu)的渴杆。
如果經(jīng)常需要同時對兩個字段進(jìn)行AND查詢,那么使用兩個單獨索引不如建立一個復(fù)合索引寥枝,因為兩個單獨索引通常數(shù)據(jù)庫只能使用其中一個,而使用復(fù)合索引因為索引本身就對應(yīng)到兩個字段上的磁奖,效率會有很大提高囊拜。散列索引
第二種索引叫做散列索引,就是通過散列函數(shù)來定位的一種索引比搭,不過很少有單獨使用散列索引的冠跷,反而是散列文件組織用的比較多。
散列文件組織就是根據(jù)一個鍵通過散列計算把對應(yīng)的記錄都放到同一個槽中身诺,這樣的話相同的鍵值對應(yīng)的記錄就一定是放在同一個文件里了蜜托,也就減少了文件讀取的次數(shù),提高了效率霉赡。
散列索引呢就是根據(jù)對應(yīng)鍵的散列碼來找到最終的索引項的技術(shù)橄务,其實和B樹就差不多了,也就是一種索引之上的二級輔助索引穴亏,我理解散列索引都是二級或更高級的稀疏索引蜂挪,否則桶就太多了重挑,效率也不會很高。位圖索引
位圖索引是一種針對多個字段的簡單查詢設(shè)計的一種特殊的索引棠涮,適用范圍比較小谬哀,只適用于字段值固定并且值的種類很少的情況,比如性別严肪,只能有男和女史煎,或者級別,狀態(tài)等等诬垂,并且只有在同時對多個這樣的字段查詢時才能體現(xiàn)出位圖的優(yōu)勢劲室。
位圖的基本思想就是對每一個條件都用0或者1來表示,如有5條記錄结窘,性別分別是男很洋,女,男隧枫,男喉磁,女,那么如果使用位圖索引就會建立兩個位圖官脓,對應(yīng)男的10110和對應(yīng)女的01001,這樣做有什么好處呢协怒,就是如果同時對多個這種類型的字段進(jìn)行and或or查詢時,可以使用按位與和按位或來直接得到結(jié)果了卑笨。MySQL不支持
三種索引實現(xiàn)方式的比較
- B+樹最常用孕暇,性能也不差,用于范圍查詢和單值查詢都可以赤兴。特別是范圍查詢妖滔,非得用B+樹這種順序的才可以了。
- HASH的如果只是對單值查詢的話速度會比B+樹快一點桶良,但是ORACLE好像不支持HASH索引座舍,只支持HASH表空間。
- 位圖的使用情況很局限陨帆,只有很少的情況才能用曲秉,一定要確定真正適合使用這種索引才用(值的類型很少并且需要復(fù)合查詢,比如性別)疲牵,否則建立一大堆位圖就一點意義都沒有了承二。
B+樹的基本原理?
MySQL是怎么用B+樹?
索引的數(shù)據(jù)結(jié)構(gòu)?
使用索引查詢一定能提高查詢的性能嗎?
通常,通過索引查詢數(shù)據(jù)比全表掃描要快.但是我們也必須注意到它的代價:
索引需要空間來存儲,也需要定期維護(hù), 每當(dāng)有記錄在表中增減或索引列被修改時,索引本身也會被修改. 這意味著每條記錄的INSERT,DELETE,UPDATE將為此多付出4,5 次的磁盤I/O. 因為索引需要額外的存儲空間和處理,那些不必要的索引反而會使查詢反應(yīng)時間變慢.使用索引查詢不一定能提高查詢性能,索引范圍查詢(INDEX RANGE SCAN)適用于兩種情況:
基于一個范圍的檢索 一般查詢返回結(jié)果集小于表中記錄數(shù)的30%
基于非唯一性索引的檢索 對于建立索引的列纲爸,數(shù)據(jù)是均勻分布好還是不均勻分布好數(shù)據(jù)均勻分布比較好亥鸠。最好每條記錄的索引列的值各不相同,比如ID缩焦,這樣查找效率最高读虏。比如年齡,對于千萬級的大表袁滥,分布還是太集中了盖桥,加上索引也沒有太大用處。
聚簇索引是怎么存在B+樹里面的?
聚簇索引索引和非聚簇索引的區(qū)別
聚簇索引:
索引順序與表中記錄的物理順序一致
非聚簇索引:
索引順序與表中記錄的物理順序無關(guān)
復(fù)合索引
Mysql從左到右的使用索引中的字段题翻,一個查詢可以只使用索引中的一部份揩徊,但只能是最左側(cè)部分。例如索引是key index (a,b,c)嵌赠。 可以支持a | a,b| a,b,c 3種組合進(jìn)行查找塑荒,但不支持 b,c進(jìn)行查找 ,當(dāng)最左側(cè)字段是常量引用時姜挺,索引就十分有效齿税。
有三種查詢,1)字段A查詢炊豪,2)字段B查詢凌箕,3)字段A和字段B復(fù)合查詢,至少需要建立幾個索引词渤。
三種查詢對應(yīng)的索引:idx_A牵舱,idx_B,idx_A_B
至少2個索引缺虐,如果是按照AB順序的復(fù)合查詢芜壁,那么需要idx_B和idx_A_B索引。因為復(fù)合idx_A_B只支持A或者AB高氮,不支持B查詢
參考一:mysql數(shù)據(jù)庫復(fù)合索引
MySQL查詢記錄時慧妄,每次只使用一個索引
原因:
- MySQL的查詢SQL會經(jīng)過查詢優(yōu)化器優(yōu)化,生成執(zhí)行計劃纫溃,再進(jìn)行查詢腰涧;
優(yōu)化過程中贴捡,如果要分析兩個索引赵哲,那么整個查詢時間將會比使用一個索引進(jìn)行查詢的時間長抱环; - 另一方面碳默,不使用索引直接掃描全表的時間又比使用一個索引查詢時間長嗤栓,所以MySQL只使用一個索引爱榕;
強制使用指定的索引:
如果有多個索引茫因,MySQL會自己選擇使用其中一個痰娱,當(dāng)然口芍,我們自己也可以強制讓它使用某一個索引(select * from table force index(ziduan1_index) limit 2;(強制使用索引"ziduan1_index"))箍铲。
參考一:數(shù)據(jù)庫中查詢記錄時是否每次只能使用一個索引?
100個字段都是經(jīng)常查詢的鬓椭,如何建索引颠猴?是對這100個字段关划,分別建立索引?還是對這100個字段翘瓮,建立復(fù)合索引
分析:
- 對于經(jīng)常有INSERT贮折,DELETE,UPDATE的表资盅,索引超過10個開銷會太大调榄,會影響性能。
- 一個表哪怕只做查詢操作呵扛,索引也不宜過多每庆,因為索引太多會導(dǎo)致查詢選擇索引出現(xiàn)開銷(當(dāng)然指定了索引可以最低限度的降低開銷)。
- 建立索引要從全局考慮今穿,就是不要只考慮一張表的索引怎么建缤灵,而是要考慮整個模塊的索引怎么建,一般在一個表上索引不要超過5個蓝晒。
事務(wù)(ACID)
含義:
作為單個邏輯工作單元執(zhí)行的一系列操作凤价,要么完全地執(zhí)行,要么完全地不執(zhí)行
原則:
原子性(Atomicity):一個事務(wù)(Transaction)中的所有操作拔创,要么全部完成利诺,要么全部不完成,不會結(jié)束在中間某個環(huán)節(jié)剩燥。事務(wù)在執(zhí)行過程中發(fā)生錯誤慢逾,會被回滾(Rollback)到事務(wù)開始前的狀態(tài),就像這個事務(wù)從來沒有執(zhí)行過一樣灭红。
一致性(Consistency): 在事務(wù)開始之前和事務(wù)結(jié)束以后侣滩,數(shù)據(jù)庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的默認(rèn)規(guī)則变擒,這包含資料的精準(zhǔn)度君珠、串聯(lián)新以及后續(xù)數(shù)據(jù)庫可以自發(fā)性地完成預(yù)定的工作。A轉(zhuǎn)賬給B娇斑,執(zhí)行事務(wù)之前:A+B=100策添,執(zhí)行事務(wù)之后:A+B=100
隔離性(Isolation): 當(dāng)兩個或者多個事務(wù)并發(fā)訪問(此處訪問指查詢和修改的操作)數(shù)據(jù)庫的同一數(shù)據(jù)時所表現(xiàn)出的互相關(guān)系。事務(wù)隔離分為不同的級別毫缆,包括讀不提交(Read uncommitted)唯竹、讀提交(Read committed)、可重復(fù)讀(Repeatable read)和串行化(Serializable)苦丁。多個事務(wù)并發(fā)訪問相互之間不影響浸颓,A事務(wù)的結(jié)果不會覆蓋B事務(wù)的結(jié)果
持久性(Durability): 在事務(wù)完成以后,該事務(wù)對數(shù)據(jù)庫所作的更改便持久地保存在數(shù)據(jù)庫之中,而且是完全的产上。事務(wù)一旦提交棵磷,對數(shù)據(jù)庫數(shù)據(jù)的改變就是永久性的
由于一項操作通常會包含許多子操作,而這些子操作可能會因為硬件的損壞或其他因素產(chǎn)生問題晋涣,要正確實現(xiàn)ACID并不容易泽本。ACID建議數(shù)據(jù)庫將所有需要更新以及修改的資料一次操作完畢,但實際上并不可行姻僧。
目前主要有兩種方式實現(xiàn)ACID:
第一種是Write ahead logging,也就是日志式的方式蒲牧。
第二種是Shadow paging撇贺。
Write ahead logging(預(yù)寫日志):
- 事務(wù)所引起的所有改動都要記錄在日志中,在事務(wù)提交完成之前冰抢,所有的這些記錄必須被寫入硬盤松嘶;
- 一個數(shù)據(jù)庫的緩沖頁直到被記入日志后才能發(fā)生修改。直到緩沖頁對應(yīng)的日志被寫入硬盤后挎扰,該緩沖頁才會存入硬盤翠订;
- 當(dāng)緩沖頁被修改和日志被更新修改時,必須加上互斥鎖遵倦,以保證改動被記錄到日志中的順序與它發(fā)生的順序是一致的尽超。
以上規(guī)則的結(jié)果:
如果一條日志記錄未被存入硬盤,則它可以被忽略梧躺,因為該日志中包含的改動一定屬于未提交的事務(wù)似谁。此外,這樣的日志不能反映已持久化在數(shù)據(jù)庫中的改動掠哥;
日志記錄按順序記錄系統(tǒng)的改動巩踏。加鎖協(xié)議(latch protocol)保證如果有對于同一頁改動的兩條日志記錄,則兩條記錄的順序反映對頁發(fā)生改變的順序续搀。
事務(wù)隔離級別
-
讀未提交(Read uncommitted): 允許讀取還未提交的改變了的數(shù)據(jù)塞琼。可能導(dǎo)致臟禁舷、幻彪杉、不可重復(fù)讀。
讀已提交(Read committed) 允許在并發(fā)事務(wù)已經(jīng)提交后讀取牵咙≡谘龋可防止臟讀,但是幻讀和不可重復(fù)讀仍可發(fā)生霜大。 - 可重復(fù)讀(Repeatable read): 對相同字段的多次讀取是一致的构哺,除非數(shù)據(jù)被事務(wù)本身改變。可防止臟曙强、不可重復(fù)讀残拐,但是幻讀仍可能發(fā)生。這個是MySQL的的默認(rèn)事務(wù)隔離級別
- 串行化(Serializable): 完全服從數(shù)據(jù)庫四種隔離級別碟嘴,確保不發(fā)生臟溪食、幻、不可重復(fù)讀娜扇。速度最慢错沃,它是通過完全鎖定在事務(wù)中涉及的數(shù)據(jù)表來完成的,事務(wù)按順序串行執(zhí)行雀瓢。
不考慮隔離性枢析,會引發(fā)一下問題:
臟讀: 一個事務(wù)讀取了另一個事務(wù)改寫但還未提交的數(shù)據(jù),如果這些數(shù)據(jù)被回滾刃麸,則讀到的數(shù)據(jù)是無效的醒叁。讀到無效數(shù)據(jù),導(dǎo)致查詢結(jié)果前后不一致泊业。
不可重復(fù)讀: 在同一個事務(wù)中把沼,讀到另一個事務(wù)已經(jīng)提交更新的數(shù)據(jù)。讀到更新的數(shù)據(jù)吁伺,導(dǎo)致多次讀取同一個數(shù)據(jù)返回的結(jié)果有所不同饮睬。ORACLE默認(rèn)是這個級別。
幻讀: 一個事務(wù)讀取了幾行記錄后篮奄,另一個事務(wù)插入一些記錄续捂,幻讀就發(fā)生了。在后來的查詢中宦搬,第一個事務(wù)就會發(fā)現(xiàn)有些原來沒有的記錄牙瓢。讀取到新的記錄
關(guān)系型數(shù)據(jù)庫的范式
第一范式: 每個屬性不可再分
第二范式: 消除部分依賴,滿足第一范式间校,表中的非主屬性必須完全依賴于主鍵(全部主屬性)
第三范式: 消除傳遞依賴矾克,滿足第二范式,非主屬性必須互不依賴
視圖
視圖是一種虛擬的表憔足,具有和物理表相同的功能胁附。可以對視圖進(jìn)行增滓彰,改控妻,查,操作揭绑,試圖通常是有一個表或者多個表的行或列的子集弓候。對視圖的修改不影響基本表郎哭。它使得我們獲取數(shù)據(jù)更容易,相比多表查詢菇存。
只暴露部分字段給訪問者夸研,所以就建一個虛表,就是視圖依鸥。
查詢的數(shù)據(jù)來源于不同的表亥至,而查詢者希望以統(tǒng)一的方式查詢,這樣也可以建立一個視圖贱迟,把多個表查詢結(jié)果聯(lián)合起來姐扮,查詢者只需要直接從視圖中獲取數(shù)據(jù),不必考慮數(shù)據(jù)來源于不同表所帶來的差異
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).
速度: 一般來說: drop> truncate >delete - delete語句是dml,這個操作會放到rollback segement中,事務(wù)提交之后才生效;
- 如果有相應(yīng)的trigger,執(zhí)行的時候?qū)⒈挥|發(fā). truncate,drop是ddl, 操作立即生效,原數(shù)據(jù)不放到rollback segment中,不能回滾. 操作不觸發(fā)trigger.
drop、delete與truncate分別在什么場景之下使用萍肆?
- 不再需要一張表的時候袍榆,用drop
- 想刪除部分?jǐn)?shù)據(jù)行時候,用delete塘揣,并且?guī)蟱here子句
保留表而刪除所有數(shù)據(jù)的時候用truncate
SQL 約束有哪幾種包雀?
- NOT NULL: 用于控制字段的內(nèi)容一定不能為空(NULL)。
- UNIQUE: 控件字段內(nèi)容不能重復(fù)亲铡,一個表允許有多個 Unique 約束才写。
- PRIMARY KEY: 也是用于控件字段內(nèi)容不能重復(fù),但它在一個表只允許出現(xiàn)一個奖蔓。
- FOREIGN KEY: 用于預(yù)防破壞表之間連接的動作赞草,也能防止非法數(shù)據(jù)插入外鍵列,因為它必須是它指向的那個表中的值之一吆鹤。
- CHECK: 用于控制字段的值范圍厨疙。
- DEFAULT: 用于設(shè)置新記錄的默認(rèn)值。
sql注入疑务,如何避免
- sql注入:用戶輸入的數(shù)據(jù)沾凄,未經(jīng)檢測,變成了sql語句的一部分知允,造成意外的結(jié)果輸出撒蟀。
- 避免sql注入:避免數(shù)據(jù)變成代碼被執(zhí)行,對sql語句進(jìn)行預(yù)編譯和查詢參數(shù)綁定温鸽,在SQL語句中放置占位符'?'保屯,然后將帶有占位符的SQL語句傳給數(shù)據(jù)庫編譯,執(zhí)行的時候才將用戶輸入的數(shù)據(jù)作為執(zhí)行的參數(shù)傳給用戶。這樣的操作不僅使得SQL語句在書寫的時候不再需要拼接配椭,看起來也更直接虫溜,而且用戶輸入的數(shù)據(jù)也沒有機會被送到數(shù)據(jù)庫的SQL解釋器被編譯執(zhí)行,也不會越權(quán)變成代碼股缸。
實例:登錄界面用戶名輸入:admin' or 1=1 '
主鍵衡楞、外鍵、候選鍵敦姻、超鍵
- 超鍵:在關(guān)系中能唯一標(biāo)識元組的屬性集稱為關(guān)系模式的超鍵瘾境。一個屬- 性可以為作為一個超鍵,多個屬性組合在一起也可以作為一個超鍵镰惦。超- 鍵包含候選鍵和主鍵迷守。
- 候選鍵:是最小超鍵,即沒有冗余元素的超鍵旺入。
- 主鍵:數(shù)據(jù)庫表中對儲存數(shù)據(jù)對象予以唯一和完整標(biāo)識的數(shù)據(jù)列或?qū)傩缘慕M合兑凿。一個數(shù)據(jù)列只能有一個主鍵,且主鍵的取值不能缺失茵瘾,即不能為空值(Null)礼华。
- 外鍵:在一個表中存在的另一個表的主鍵稱此表的外鍵。
MySQL的常用引擎
在MySQL數(shù)據(jù)庫中拗秘,常用的引擎主要就是2個:Innodb和MyIASM圣絮。這篇文章將主要介紹這兩個引擎,以及該如何去選擇引擎雕旨,最后在提一下這2種引擎所使用的數(shù)據(jù)結(jié)構(gòu)是什么扮匠。
Innodb引擎。
Innodb引擎提供了對數(shù)據(jù)庫ACID事務(wù)的支持凡涩。并且還提供了行級鎖和外鍵的約束棒搜。它的設(shè)計的目標(biāo)就是處理大數(shù)據(jù)容量的數(shù)據(jù)庫系統(tǒng)。它本身實際上是基于Mysql后臺的完整的系統(tǒng)活箕。Mysql運行的時候帮非,Innodb會在內(nèi)存中建立緩沖池,用于緩沖數(shù)據(jù)和索引讹蘑。但是末盔,該引擎是不支持全文搜索的。同時座慰,啟動也比較的慢陨舱,它是不會保存表的行數(shù)的。當(dāng)進(jìn)行Select count(*) from table指令的時候版仔,需要進(jìn)行掃描全表游盲。
所以當(dāng)需要使用數(shù)據(jù)庫的事務(wù)時误墓,該引擎就是首選。由于鎖的粒度小益缎,寫操作是不會鎖定全表的谜慌。所以在并發(fā)度較高的場景下使用會提升效率的。
MyIASM引擎
mysql5.5之前莺奔,它是MySql的默認(rèn)引擎欣范,5.5開始默認(rèn)引擎是Innodb,但不提供事務(wù)的支持令哟,也不支持行級鎖和外鍵恼琼。因此當(dāng)執(zhí)行Insert插入和Update更新語句時,即執(zhí)行寫操作的時候需要鎖定這個表屏富。所以會導(dǎo)致效率會降低晴竞。不過和Innodb不同的是,MyIASM引擎是保存了表的行數(shù)狠半,于是當(dāng)進(jìn)行Select count(*) from table語句時噩死,可以直接的讀取已經(jīng)保存的值而不需要進(jìn)行掃描全表。
所以神年,如果表的讀操作遠(yuǎn)遠(yuǎn)多于寫操作時已维,并且不需要事務(wù)的支持的×鲂洌可以將MyIASM作為數(shù)據(jù)庫引擎的首先衣摩。
這兩種引擎的選擇昂验。其實上面已經(jīng)提到了捂敌。這里我在補充了兩點:
- 大容量的數(shù)據(jù)集時趨向于選擇Innodb。因為它支持事務(wù)處理和故障的恢復(fù)既琴。Innodb可以利用數(shù)據(jù)日志來進(jìn)行數(shù)據(jù)的恢復(fù)占婉。主鍵的查詢在Innodb也是比較快的。
- 大批量的插入語句時(這里是INSERT語句)在MyIASM引擎中執(zhí)行的比較的快甫恩,但是UPDATE語句在Innodb下執(zhí)行的會比較的快逆济,尤其是在并發(fā)量大的時候。
兩種引擎所使用的索引的數(shù)據(jù)結(jié)構(gòu)是什么磺箕?
答案是都是B+樹奖慌。
- 對于MyIASM引擎來說,B+樹的數(shù)據(jù)結(jié)構(gòu)中存儲的內(nèi)容實際上是實際數(shù)據(jù)的地址值松靡。也就是說它的索引和實際數(shù)據(jù)是分開的简僧,只不過使用索引指向了實際數(shù)據(jù)。這種索引的模式被稱為非聚集索引雕欺。
- Innodb引擎的索引的數(shù)據(jù)結(jié)構(gòu)也是B+樹岛马,只不過數(shù)據(jù)結(jié)構(gòu)中存儲的都是實際的數(shù)據(jù)棉姐,這種索引有被稱為聚集索引。
mysql一般用的什么數(shù)據(jù)庫引擎
mysql5.5以后默認(rèn)的是InnoDB存儲引擎
InnoDB和MyISAM之間的區(qū)別啦逆、應(yīng)用場景
區(qū)別:
- MyISAM不支持事務(wù)伞矩,InnoDB是事務(wù)類型的存儲引擎
- MyISAM只支持表級鎖,BDB支持頁級鎖和表級鎖默認(rèn)為頁級鎖夏志,而InnoDB支持行級鎖和表級鎖默認(rèn)為行級鎖
- MyISAM引擎不支持外鍵乃坤,InnoDB支持外鍵
- MyISAM引擎的表在大量高并發(fā)的讀寫下會經(jīng)常出現(xiàn)表損壞的情況
- 對于count()查詢來說MyISAM更有優(yōu)勢
- InnoDB是為處理巨大數(shù)據(jù)量時的最大性能設(shè)計,它的CPU效率可能是任何其它基于磁盤的關(guān)系數(shù)據(jù)庫引擎所不能匹敵的
- MyISAM支持全文索引(FULLTEXT)盲镶,InnoDB不支持
- MyISAM引擎的表的查詢侥袜、更新、插入的效率要比InnoDB高
應(yīng)用場景:
MyISAM:(1)做很多count 的計算溉贿;(2)插入不頻繁枫吧,查詢非常頻繁;(3)沒有事務(wù)宇色。
InnoDB:(1)可靠性要求比較高九杂,或者要求事務(wù);(2)表更新和查詢都相當(dāng)?shù)念l繁宣蠕,并且行鎖定的機會比較大的情況例隆。
數(shù)據(jù)庫連接
通過JDBC訪問數(shù)據(jù)庫包含下面哪幾步?
- 加載JDBC驅(qū)動程序
- 提供JDBC連接的URL
- 創(chuàng)建數(shù)據(jù)庫的連接
- 創(chuàng)建一個Statement
- 執(zhí)行SQL語句
- 處理結(jié)果
- 關(guān)閉JDBC對象
存儲過程
- 存儲過程是一個預(yù)編譯的代碼塊抢蚀,執(zhí)行效率比較高
- 一個存儲過程替代大量T_SQL語句 镀层,可以降低網(wǎng)絡(luò)通信量,提高通信速率
-- 可以一定程度上確保數(shù)據(jù)安全
觸發(fā)器的作用
觸發(fā)器是一種特殊的存儲過程皿曲,主要是通過事件來觸發(fā)而被執(zhí)行的唱逢。它可以強化約束,來維護(hù)數(shù)據(jù)的完整性和一致性屋休,可以跟蹤數(shù)據(jù)庫內(nèi)的操作從而不允許未經(jīng)許可的更新和變化坞古。可以聯(lián)級運算劫樟。如痪枫,某表上的觸發(fā)器上包含對另一個表的數(shù)據(jù)操作,而該操作又會導(dǎo)致該表觸發(fā)器被觸發(fā)叠艳。
數(shù)據(jù)庫的樂觀鎖和悲觀鎖
數(shù)據(jù)庫管理系統(tǒng)(DBMS)中的并發(fā)控制的任務(wù)是確保在多個事務(wù)同時存取數(shù)據(jù)庫中同一數(shù)據(jù)時不破壞事務(wù)的隔離性和統(tǒng)一性以及數(shù)據(jù)庫的統(tǒng)一性奶陈。
樂觀并發(fā)控制(樂觀鎖)和悲觀并發(fā)控制(悲觀鎖)是并發(fā)控制主要采用的技術(shù)手段。
- 悲觀鎖:假定會發(fā)生并發(fā)沖突附较,屏蔽一切可能違反數(shù)據(jù)完整性的操作
- 樂觀鎖:假設(shè)不會發(fā)生并發(fā)沖突吃粒,只在提交操作時檢查是否違反數(shù)據(jù)完整性。
悲觀鎖和樂觀鎖的區(qū)別以及應(yīng)用場景
區(qū)別:
- 悲觀鎖: 每次去拿數(shù)據(jù)的時候都認(rèn)為別人會修改翅睛,所以每次在拿數(shù)據(jù)的時候都會上鎖声搁,這樣別人想拿這個數(shù)據(jù)就會block直到它拿到鎖黑竞。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫里邊就用到了很多這種鎖機制,比如行鎖疏旨,表鎖等很魂,讀鎖,寫鎖等檐涝,都是在做操作之前先上鎖遏匆。比較適合寫入操作比較頻繁的場景,如果出現(xiàn)大量的讀取操作谁榜,每次讀取的時候都會進(jìn)行加鎖幅聘,這樣會增加大量的鎖的開銷,降低了系統(tǒng)的吞吐量窃植。
- 樂觀鎖: 每次去拿數(shù)據(jù)的時候都認(rèn)為別人不會修改帝蒿,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數(shù)據(jù)巷怜,可以使用版本號等機制葛超。樂觀鎖適用于多讀的應(yīng)用類型,這樣可以提高吞吐量延塑,像數(shù)據(jù)庫如果提供類似于write_condition機制的其實都是提供的樂觀鎖绣张。比較適合讀取操作比較頻繁的場景,如果出現(xiàn)大量的寫入操作关带,數(shù)據(jù)發(fā)生沖突的可能性就會增大侥涵,為了保證數(shù)據(jù)的一致性,應(yīng)用層需要不斷的重新獲取數(shù)據(jù)宋雏,這樣會增加大量的查詢操作芜飘,降低了系統(tǒng)的吞吐量。
應(yīng)用場景: 讀取頻繁使用樂觀鎖好芭,寫入頻繁使用悲觀鎖燃箭。
MySQL分表冲呢、分區(qū)舍败、分庫
- 分表:將一張表分成多個小表。
- 分區(qū):一張表的數(shù)據(jù)分成多個區(qū)塊敬拓,這些區(qū)塊可以在同一個磁盤上邻薯,也可以在不同的磁盤上。
- 分庫:一個數(shù)據(jù)庫按城市(或者其他標(biāo)準(zhǔn))分成多個數(shù)據(jù)庫乘凸。
參考一:MYSQL分庫分表總結(jié)
連表查詢:笛卡爾積通過什么連接得到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語句:
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ù)庫中某個表查詢和存取數(shù)據(jù)量很大時怎么處理
數(shù)據(jù)庫設(shè)計:
SQL語句:
Java代碼:
參考一:在一個千萬級的數(shù)據(jù)庫查尋中壹罚,如何提高查詢效率?
做項目時怎么設(shè)計數(shù)據(jù)庫寿羞,怎么決定主鍵
因為我自己談到用過redis,所以又問了我redis的原理和優(yōu)勢
數(shù)據(jù)庫的底層設(shè)計猖凛,文件如何存儲,數(shù)據(jù)如何查詢
MongoDB和MySQL的區(qū)別
MongoDB:日志
存儲方式:虛擬內(nèi)存+持久化绪穆。
查詢語句:是獨特的Mongodb的查詢方式辨泳。
適合場景:事件的記錄,內(nèi)容管理或者博客平臺等等玖院。
架構(gòu)特點:可以通過副本集菠红,以及分片來實現(xiàn)高可用。
數(shù)據(jù)處理:數(shù)據(jù)是存儲在硬盤上的难菌,只不過需要經(jīng)常讀取的數(shù)據(jù)會被加載到內(nèi)存中试溯,將數(shù)據(jù)存儲在物理內(nèi)存中,從而達(dá)到高速讀寫郊酒。
不支持事務(wù)
參考一:數(shù)據(jù)庫-面試題(持續(xù)更新)
參考二:http://www.cnblogs.com/remember-forget/p/6140112.html
參考三:mysql數(shù)據(jù)庫面試總結(jié)
參考四:數(shù)據(jù)庫面試寶典