參考文章:
事務
1、什么是數據庫事務?事務的屬性?
一個邏輯單元要成為事務,必須滿足ACID的屬性,即原子性、一致性、隔離性、持久性
原子性:
一致性:
隔離性:
持久性:
AUTOCOMMIT
2、並發事務帶來哪些問題?
臟讀:
丟失修改:
不可重復讀:
幻讀:
不可重復讀和幻讀區別:
不可重復讀的重點是對單條記錄的修改,比如多次讀取一條記錄發現其中某些列的值被修改;幻讀的重點在於對多條記錄的新增或者刪除,比如多次讀取一個范圍的記錄發現記錄增多或減少了。
產生並發不一致性問題主要原因是破壞了事務的隔離性,解決方法是通過並發控制來保證隔離性。並發控制可以通過加鎖來實現,但是加鎖操作需要用戶自己控制,相當復雜。數據庫管理系統提供了事務的隔離級別,讓用戶以一種更輕松的方式處理並發一致性問題。
3、事務隔離級別有哪些? MySQL的默認隔離級別是?
SQL 標准定義了四個隔離級別:
READ-UNCOMMITTED(未提交讀):
最低的隔離級別,允許讀取尚未提交的數據變更,可能會導致臟讀、幻讀或不可重復讀。
READ-COMMITTED(提交讀):4、事務隔離級別的RR和RC是怎么實現的
相關語法
1、建表的原則(三大范式)
第一范式(1NF)
第二范式
第三范式
BC范式
2、MySQL外連接知道嗎?左外連接和右外連接是什么,有什么區別?什么是內連接,完全連接
外連接分為左外連接和右外連接
左(外)連接,左表(a_table)的記錄將會全部表示出來,而右表(b_table)只會顯示符合搜索條件的記錄。右表記錄不足的地方均為NULL
與左(外)連接相反,右(外)連接,左表(a_table)只會顯示符合搜索條件的記錄,而右表(b_table)的記錄將會全部表示出來。左表記錄不足的地方均為NULL。
完全連接就是左表和右表都是展示所有記錄
內連接是左右表都只顯示符合搜索條件的記錄
性能優化
1、mysql性能優化
MySQL 索引
索引是在存儲引擎層實現的,而不是在服務器層實現的,所以不同存儲引擎具有不同的索引類型和實現。
索引的優點
為什么不對表的每個列創建一個索引
索引選取類型
什么場景不適合創建索引
什么樣的字段適合創建索引
索引失效:
索引物理分類
聚簇索引和非聚簇索引
聚簇索引的優缺點
索引邏輯分類
單列索引:一個索引只包含一個列,一個表可以有多個單列索引。
組合索引:一個組合索引包含兩個或兩個以上的列,
前綴索引
對於列的值較長,比如BLOB、TEXT、VARCHAR,就必須建立前綴索引,即將值的前一部分作為索引。這樣既可以節約空間,又可以提高查詢效率。但無法使用前綴索引做 ORDER BY 和 GROUP BY,也無法使用前綴索引做覆蓋掃描。
覆蓋索引
覆蓋索引的優化及限制
覆蓋索引是一種非常強大的工具,能大大提高查詢性能,只需要讀取索引而不需要讀取數據,有以下優點:
1、索引項通常比記錄要小,所以MySQL訪問更少的數據。
2、索引都按值得大小存儲,相對於隨機訪問記錄,需要更少的I/O。
3、數據引擎能更好的緩存索引,比如MyISAM只緩存索引。
4、覆蓋索引對InnoDB尤其有用,因為InnoDB使用聚集索引組織數據,如果二級索引包含查詢所需的數據,就不再需要在聚集索引中查找了。
限制:
1、覆蓋索引也並不適用於任意的索引類型,索引必須存儲列的值。
2、Hash和full-text索引不存儲值,因此MySQL只能使用BTree。
3、不同的存儲引擎實現覆蓋索引都是不同的,並不是所有的存儲引擎都支持覆蓋索引。
4、如果要使用覆蓋索引,一定要注意SELECT列表值取出需要的列,不可以SELECT * ,因為如果將所有字段一起做索引會導致索引文件過大,查詢性能下降。
最左前綴原則:
顧名思義是最左優先,以最左邊的為起點任何連續的索引都能匹配上,
注:如果第一個字段是范圍查詢需要單獨建一個索引
注:在創建聯合索引時,要根據業務需求,where子句中使用最頻繁的一列放在最左邊。這樣的話擴展性較好,比如 userid
經常需要作為查詢條件,而 mobile
不常常用,則需要把 userid
放在聯合索引的第一位置,即最左邊
同時存在聯合索引和單列索引(字段有重復的),這個時候查詢mysql會怎么用索引呢?
這個涉及到mysql本身的查詢優化器策略了,當一個表有多條索引可走時, Mysql 根據查詢語句的成本來選擇走哪條索引;
聯合索引本質:
當創建(a,b,c)聯合索引時,相當於創建了(a)單列索引,(a,b)聯合索引以及 (a,b,c)聯合索引,想要索引生效的話,只能使用 a和a,b和a,b,c三種組合;當然,我們上面測試過,a,c組合也可以,但實際上只用到了a的索引,c並沒有用到!
利用索引中的附加列,您可以縮小搜索的范圍,但使用一個具有兩列的索引 不同於使用兩個單獨的索引。復合索引的結構與電話簿類似,人名由姓和名構成,電話簿首先按姓氏對進行排序,然后按名字對有相同姓氏的人進行排序。如果您知道姓,電話簿將非常有用;如果您知道姓和名,電話簿則更為有用,但如果您只知道名不姓,電話簿將沒有用處。
所以說創建復合索引時,應該仔細考慮列的順序。對索引中的所有列執行搜索或僅對前幾列執行搜索時,復合索引非常有用;僅對后面的任意列執行搜索時,復合索引則沒有用處。
復合索引與單列索引的比較:
2. 有多條件聯合查詢時最好建聯合索引,多個單列索引在多條件查詢時優化器會選擇最優索引策略,可能只用一個索引,也可能將多個索引全用上! 但多個單列索引底層會建立多個B+索引樹,比較占用空間,也會浪費一定搜索效率,
其他知識點:
1、需要加索引的字段,要在where條件中
2、數據量少的字段不需要加索引;因為建索引有一定開銷,如果數據量小則沒必要建索引(速度反而慢)
3、避免在where子句中使用or來連接條件,因為如果倆個字段中有一個沒有索引的話,引擎會放棄索引而產生全表掃描
4、聯合索引比對每個列分別建索引更有優勢,因為索引建立得越多就越占磁盤空間,在更新數據的時候速度會更慢。另外建立多列索引時,順序也是需要注意的,應該將嚴格的索引放在前面,這樣篩選的力度會更大,效率更高。
索引的底層實現
1. B+Tree 索引
是大多數 MySQL 存儲引擎的默認索引類型。
因為不再需要進行全表掃描,只需要對樹進行搜索即可,所以查找速度快很多。
因為 B+ Tree 的有序性,所以除了用於查找,還可以用於排序和分組。
可以指定多個列作為索引列,多個索引列共同組成鍵。
適用於全鍵值、鍵值范圍和鍵前綴查找,其中鍵前綴查找只適用於最左前綴查找。如果不是按照索引列的順序進行查找,則無法使用索引。
InnoDB 的 B+Tree 索引分為主索引和輔助索引。主索引的葉子節點 data 域記錄着完整的數據記錄,這種索引方式被稱為聚簇索引。因為無法把數據行存放在兩個不同的地方,所以一個表只能有一個聚簇索引。
輔助索引的葉子節點的 data 域記錄着主鍵的值,因此在使用輔助索引進行查找時,需要先查找到主鍵值,然后再到
主索引中進行查找。
2. 哈希索引
哈希索引能以 O(1) 時間進行查找,但是失去了有序性:
無法用於排序與分組;
只支持精確查找,無法用於部分查找和范圍查找。
InnoDB 存儲引擎有一個特殊的功能叫“自適應哈希索引”,當某個索引值被使用的非常頻繁時,會在 B+Tree 索引之
上再創建一個哈希索引,這樣就讓 B+Tree 索引具有哈希索引的一些優點,比如快速的哈希查找。
3、BST(二叉查找樹)
3.4AVL樹vsRBtree: avl樹是嚴格平衡樹,而rbtree是弱平衡樹,都是通過旋轉來保持平衡,而在增刪節點時,嚴格平衡樹旋轉的次數比弱平衡旋轉的次數多,當搜索節點的次數遠遠大於增刪節點的次數時,旋轉AVL樹,當搜索節點的次數與增刪節點的次數差不多時選擇RBtree效率高。
4、磁盤讀取及預讀的過程及時間消耗?
5、btree定義?
2.若根不是葉子結點,則根節點至少有兩個子樹
3.分支節點至少擁有m/2棵子樹(除根和葉子)
4.所有葉子節點都在同一層, 這些葉子結點不存儲有效的信息
6、為什么btree查找效率高?
7、btree節點如何定義?vs二叉搜索樹
8、 b+tree 與B樹的區別
9、 為什么b+tree比btree更適合做文件的索引、數據庫索引?
1.btree在提高磁盤 io 性能同時並沒有解決元素遍歷效率低下的問題,b+tree只要遍歷葉子節點就可遍歷整棵樹。2.在數據庫中基於范圍的查找很頻繁,btree每次都要從根節點查,效率低。b+tree只要找到范圍左邊界的葉子結點,可以順着葉子結點,找到相應范圍的所有元素。
由於非終結點並不是最終指向文件內容的結點,而只是葉子結點中關鍵字的索引。所以任何關鍵字的查找必須走一條從根結點到葉子結點的路。所有關鍵字查詢的路徑長度相同,導致每一個數據的查詢效率相當
補充
真實數據庫中的B+樹應該是非常扁平的,也就是說高度非常小,也就說叉數非常多,每個結點的字樹非常多,而且B+樹的索引節點是非常小的,一次性可以加載到內存,這樣就可以用少量的內存換取只需一次訪存即可獲取到數據的恐怖效率。
B+樹的叉數可以達到1000多叉,存儲 22G 容量的表高度也才3層,一次訪存即可獲取數據。
10、b+樹和b樹分別有什么應用
11、hashmap為什么用紅黑樹不用b樹
4. 解釋一下什么是池化設計思想。什么是數據庫連接池?為什么需要數據庫連接池?
池話設計應該不是一個新名詞。我們常見的如java線程池、jdbc連接池、redis連接池等就是這類設計的代表實現。這種設計會初始預設資源,解決的問題就是抵消每次獲取資源的消耗,如創建線程的開銷,獲取遠程連接的開銷等。就好比你去食堂打飯,打飯的大媽會先把飯盛好幾份放那里,你來了就直接拿着飯盒加菜即可,不用再臨時又盛飯又打菜,效率就高了。除了初始化資源,池化設計還包括如下這些特征:池子的初始值、池子的活躍值、池子的最大值等,這些特征可以直接映射到java線程池和數據庫連接池的成員屬性中。——這篇文章對池化設計思想介紹的還不錯,直接復制過來,避免重復造輪子了。
數據庫連接本質就是一個 socket 的連接。數據庫服務端還要維護一些緩存和用戶權限信息之類的 所以占用了一些內存。我們可以把數據庫連接池是看做是維護的數據庫連接的緩存,以便將來需要對數據庫的請求時可以重用這些連接。為每個用戶打開和維護數據庫連接,尤其是對動態數據庫驅動的網站應用程序的請求,既昂貴又浪費資源。在連接池中,創建連接后,將其放置在池中,並再次使用它,因此不必建立新的連接。如果使用了所有連接,則會建立一個新連接並將其添加到池中。連接池還減少了用戶必須等待建立與數據庫的連接的時間。
這種設計會初始預設資源,解決的問題就是抵消每次獲取資源和釋放資源造成的開銷。連接池也是這樣,預先創建好一個連接池,在池中創建一定數量的連接,每當用戶需要連接數據庫,就從池中取出一個連接,使用完畢之后放回池中,這既可以減少連接創建和釋放的開銷,便於連接的管理,也可以降低用戶等待數據庫的延遲。
攻擊
sql注入攻擊
簡介:
用戶名:1 密 碼:1' OR '1'='1 那么程序接收到參數后,SQL語句就變成了:SELECT * FROM user WHERE name = '1' and password= '1' OR '1'='1 ';
用戶名:1'; DROP DATABASE root;-- 密碼:1 那么程序接收到參數后,SQL語句就變成了:SELECT * FROM user WHERE name = '1'; DROP DATABASE root;--and password= '1';
解決辦法:
MySQL 的體系結構
連接池:
管理工具和服務:
SQL接口:
解析器:
優化器:
緩存器:
存儲引擎
MyISAM存儲引擎
由於該存儲引擎不支持事務、也不支持外鍵,所以訪問速度較快。因此當對事務完整性沒有要求並以訪問為主的應用適合使用該存儲引擎。
InnoDB存儲引擎
mysql 5.5版本以后默認的存儲引擎
由於該存儲引擎在事務上具有優勢,即支持具有提交、回滾及崩潰恢復能力等事務特性,他在運行時會在內存中建立緩沖池,用於緩沖數據和索引。支持行鎖,並發度高。主鍵索引為聚簇索引,所以比MyISAM存儲引擎占用更多的磁盤空間。因此當需要頻繁的更新、刪除操作,同時還對事務的完整性要求較高,需要實現並發控制,建議選擇。
.ibd文件:存放innodb表的數據文件。
MEMORY
MEMORY存儲引擎存儲數據的位置是內存,因此訪問速度最快,但是安全上沒有保障。適合於需要快速的訪問或臨時表。
BLACKHOLE
黑洞存儲引擎,寫入的任何數據都會消失,可以應用於主備復制中的分發主庫。
存儲引擎的另一個知識總結
InnoDB 和 MyISAM 的區別:
InnoDB引擎
InnoDB引擎優點
1、支持事務處理、ACID事務特性; 2、實現了SQL標准的四種隔離級別; 3、支持行級鎖和外鍵約束,行鎖優點是粒度小,適用於高並發的頻繁表修改,高並發使性能優於 MyISAM。缺點是系統消耗較大。4、可以利用事務日志進行數據恢復。
InnoDB引擎缺點
因為它沒有保存表的行數,當使用COUNT統計時會掃描全表。
2、索引不僅緩存自身,也緩存數據,相比 MyISAM 需要更大的內存。
MyISAM引擎
MyISAM 是 MySQL 5.5.5 之前的默認引擎,它的設計目標是快速讀取。
MyISAM引擎優點
1.高性能讀取;
2.因為它保存了表的行數,當使用COUNT統計時不會掃描全表;
MyISAM引擎缺點
1、鎖級別為表鎖,表鎖優點是開銷小,加鎖快;缺點是鎖粒度大,發生鎖沖動概率較高,容納並發能力低,這個引擎適合查詢為主的業務。 2、此引擎不支持事務,也不支持外鍵。 3、INSERT和UPDATE操作需要鎖定整個表;
適用場景
MyISAM適合:(1)做很多count 的計算;(2)插入不頻繁,查詢非常頻繁;(3)沒有事務。
InnoDB適合:(1)可靠性要求比較高,或者要求事務;(2)表更新和查詢都相當的頻繁,並且表鎖定的機會比較大的情況。
補充:
OLTP用於存儲和管理日常操作的數據;
OLAP用於分析這些數據