MySQl看這一篇就夠了

MySQl看這一篇就夠了

MySQL分享

一、數據庫結構

語句

DDL(Data Definition Languages):數據定義語句,常用的語句關鍵字主要包括 create、drop、alter等操作表結構

DML(Data Manipulation Language):數據操作語句,常用的語句關鍵字主要包括 insert、delete、udpate 和select 等操作數據

DCL(Data Control Language):數據控制語句,用戶的訪問權限和安全級別。主要的語句關鍵字包括 grant、revoke 等

結構

1072053-20190801110706035-1383742253.jpg

連接者:不同語言的代碼程序和mysql的交互(SQL交互)

連接池:管理、緩沖用戶的連接,線程處理等需要緩存的需求

管理服務和工具組件:系統管理和控制工具,例如備份恢復、Mysql復制、集群等

SQL接口:接受用戶的SQL命令,并且返回用戶需要查詢的結果

解析器:對SQL進行解析,判斷語法是否正確

查詢優化器:SQL語句在查詢之前會使用查詢優化器對查詢進行優化

舉個例子

-- 下面的SQL company 和 name 都有索引,索引類型也相同,字段類型也相同
-- 索引字段能匹配的數據越少,優先使用該索引字段
select * from dept_table where company = '集團' and name = '財務部';

緩存:如果查詢緩存有命中的查詢結果,查詢語句就可以直接去查詢緩存中取數據

存儲引擎:INSERT DELETE UPDATE SELECT 數據的一種方式

存儲引擎名稱特點應用場景
InnoDB支持事務、行鎖、支持MVCC多版本并發控制,并發性高應用OLTP業務系統
MyISAM不支持事務,MySQL8之后被廢棄了,并發很低,資源利用率也很低應用OLAP業務系統,建議生產環境盡量少少使用 MyISAM 存儲引擎
MariaDB columnstore列式存儲引擎,高壓縮功能數據倉庫,OLAP業務系統
數據庫的引擎級別?
  • [ ] A. 軟件級別(即安裝MySQL時就已經指定引擎類型)
  • [ ] B. 數據庫級別
  • [ ] C. 表級別

OLTP(On-Line Transaction Processing):聯機事務處理,比如增刪改查,完成一筆交易處理

OLAP(On-Line Analytical Processing):聯機分析處理,支持復雜的分析操作,側重決策支持,做數據分析,決策,比如 ElasticSearch

SQL執行過程

1072053-20190801110738728-627038860.png

二、事務

事務特性(ACID)

原子性(A):要么全完成,要么全不完成

一致性(C):在事務開始之前和事務結束以后,數據庫的完整性約束沒有被破壞(比如A給B轉賬100元,A減少100,B增加100)

隔離性(I):事務之間互不干擾

持久性(D):事務提交后保存起來了

隔離級別(對執行事務起作用)

讀未提交(read uncommitted):A事務變更后沒提交,B能看到

讀已提交(read committed):A事務變更后提交,B才能看到

可重復讀(repeatable read):一個事務執行過程中看到的數據,總是跟這個事務在啟動時看到的數據是一致的

串行化(serializable):同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現讀寫鎖沖突的時候,后訪問的事務必須等前一個事務執行完成,才能繼續執行

并發問題

臟讀:讀未提交的隔離級別下,A事務讀到B更新卻沒commit的數據

不可重復讀:側重修改,A事務兩次讀取同一數據兩次不一致

幻讀:側重數據增減,A事務兩次讀取數據不同

事務隔離級別與并發問題

事務隔離級別臟讀不可重復讀幻讀
讀未提交(read uncommitted)
讀已提交(read committed)
可重復讀(repeatable read)
串行化(serializable)

驗證事務的隔離級別

事務A事務B
begin;begin;
select * from dept_table; --V1
select * from dept_table; --V2
update dept_table set name = '研發部' where id = 1;
select * from dept_table; --V3
commit;
select * from dept_table; --V4
commit;
select * from dept_table; --V5

事務相關SQL

# 設置事務隔離級別
set session transaction isolation level read uncommitted;set session transaction isolation level read committed;set session transaction isolation level repeatable read;# 查詢當前事務隔離級別
select @@tx_isolation;# 查詢全局事務隔離級別
select @@global.tx_isolation;# 開啟事務
begin;
start transaction;# 提交事務
commit;# 回滾事務
rollback;

隔離級別的實現

多版本并發控制 MVCC(Multi-Version Concurrency Control): MySQL 的 InnoDB 存儲引擎實現隔離級別的一種具體方式,在每行數據都增加兩個隱藏字段,一個記錄創建的版本號,一個記錄刪除的版本號,用于實現提交讀和可重復讀這兩種隔離級別。而未提交讀隔離級別總是讀取最新的數據行,無需使用 MVCC。可串行化隔離級別需要對所有讀取的行都加鎖,單純使用 MVCC 無法實現

版本號
  1. 系統版本號:是一個遞增的數字,每開始一個新的事務,系統版本號就會自動遞增

  2. 事務版本號:事務開始時的系統版本號

可重復讀的操作
  1. SELECT:讀取創建版本 <= 當前事務版本號,并且刪除版本為空或大于當前事務版本號的記錄。這樣可以保證在讀取之前記錄是存在的
  2. INSERT:將當前事務的版本號保存至行的創建版本號
  3. UPDATE:新插入一行,并以當前事務的版本號作為新行的創建版本號,同時將原記錄行的刪除版本號設置為當前事務版本號
  4. DELETE:將當前事務的版本號保存至行的刪除版本號

插入一條新數據(事務版本號 = 1)

idnamecreate_versiondelete_version
1Tom1

執行更新操作(事務版本號 = 2)

update table set name= 'Tom2' where id = 1;
idnamecreate_versiondelete_version
1Tom12
1Tom22

刪除操作(事務版本號 = 3)

delete from table where id = 1;
idnamecreate versiondelete version
1Tom223

查詢操作要滿足兩個條件才能查詢出來

  1. 刪除版本號 大于 當前事務版本號或為空,就是說刪除操作是在當前事務啟動之后做的
  2. 創建版本號 小于或者等于 當前事務版本號 ,就是說記錄創建是在事務中(等于的情況)或者事務啟動之前
可重復讀情況下的演示
-- 1. T事務(假設:當前事務版本號 = 1)插入一條數據
-- create_version = 1 delete_version = null
insert into `up`.`dept_table`(`id`, `company`, `name`) values (5, '總部', '綜合創新部');-- 1. A事務(假設:當前事務版本號 = 2) 查詢數據 4條結果
select * from dept_table; -- 2. B事務(假設:當前事務版本號 = 3) 更新ID = 1 的數據
update dept_table set name = '金融服務部' where id = 5;-- 3. A事務繼續查詢
select * from dept_table; 
快照讀

當執行select操作時 InnoDB默認會執行快照讀,會記錄下這次select后的結果,之后select 的時候就會返回這次快照的數據,即使其他事務提交了不會影響當前select的數據,這就實現了可重復讀了。快照的生成當在第一次執行select的時候,也就是說假設當A開啟了事務,然后沒有執行任何操作,這時候B insert了一條數據然后commit,這時候A執行 select,那么返回的數據中就會有B添加的那條數據。之后無論再有其他事務commit都沒有關系,因為快照已經生成了,后面的select都是根據快照來的

示例1 B事務的查詢結果是否有A新增的數據?

A事務B事務
start transaction;start transaction;
insert into up.dept_table(id, company, name) values (6, '總部', '綜合創新部');
select * from dept_table;
commit;
select * from dept_table;
commit

示例2 B事務的兩次查詢結果是否相同?第二次查詢是否有A新增的數據?

A事務B事務
start transaction;start transaction;
select * from dept_table;
insert into up.dept_table(id, company, name) values (6, '總部', '綜合創新部');
select * from dept_table;
commit;
select * from dept_table;
commit;
當前讀

對數據修改的操作(update、insert、delete、select …... lock in share mode、select …... for update)都是采用當前讀的模式。在執行這幾個操作時會讀取最新的記錄,即使是別的事務提交的數據也可以查詢到。假設要update一條記錄,但是在另一個事務中已經delete掉這條數據并且commit了,如果update就會產生沖突,所以在update的時候需要知道最新的數據。也正是因為這樣所以才導致上面我們測試的那種情況

示例

A事務B事務
start transaction;start transaction;
select * from dept_table; -- V1
insert into up.dept_table(id, company, name) values (6, '總部', '綜合創新部');
commit;
select * from dept_table; -- V2
update dept_table set name = '新部門' where id = 6;
select * from dept_table; -- V3
commit;
快照讀當前讀
select * from tableselect * from table for update
select * from table lock in share mode
insert、delete、insert

三、InnoDB的鎖

鎖概念

鎖作用

數據庫鎖機制簡單來說,就是數據庫為了保證數據的一致性,使各種共享資源在被并發訪問時變得有序而設計的一種規則

鎖機制

MySQL的鎖機制比較簡單,最顯著的特點時不同的存儲引擎支持不同的鎖機制,我們鎖知道的,InnoDB支持行鎖,有時也會升級為表鎖,MyISAM只支持表鎖

行鎖和表鎖的特點
表鎖行鎖
開銷小開銷大
加鎖快加鎖慢
不會出現死鎖會出現死鎖
鎖粒度大鎖粒度小
發生鎖沖突的概率高發生鎖沖突的概率低
并發度相對低并發度相對高

InnoDB的鎖類型

讀鎖(共享鎖)

簡稱S鎖,若事務T對數據對象加上讀鎖,則事務T可以讀但不能修改,其他事務只能再對該數據加讀鎖不能加寫鎖,直到T釋放該數據的讀鎖。即一個事務在讀取一個數據行時,其他事務也可以讀,但不能對該數據進行增刪改的操作

讀鎖的實現方式

  1. 自動提交模式下的select查詢語句,不需要加任何鎖,直接返回查詢結果,這是一致性非鎖定讀
  2. 通過 select ...... lock in share mode 在被讀取的行記錄或行記錄的范圍上加一個鎖,讓其他事務可以讀,但是想要申請寫鎖,就要被阻塞
-- 查詢是否自動提交模式
show variables like '%auto%';
寫鎖(排它鎖)

簡稱X鎖,若事務T對數據對象加上寫鎖,事務T可以讀也可以修改,其他事務不能再對該數據加任何鎖,不能讀也不能寫,直到T釋放該數據上的鎖。即一個事務獲取了一個數據行的寫鎖,其他事務就不能再獲取該行的其他鎖,寫鎖優先級最高

寫鎖的實現方式

  1. INSERT、DELETE、UPDATE語句的操作都會對行記錄加寫鎖
  2. 通過 select ...... for update 對讀取的記錄行上加寫鎖,其他任何事務就不能對鎖定的行上加任何鎖了,否則會被阻塞
MDL鎖(meta data lock)

在事務A中開啟查詢,會自動獲得一個MDL鎖,事務B就不可以執行任何DDL語句的操作

事務A事務B
begin;begin;
select * from score_table;
alter table score_table add num tinyint(1) not null default 0; -- 阻塞
commit;
commit;
-- 查詢進程列表
show full processlist;
意向鎖

在MySQL存儲引擎InnoDB中,意向鎖是表級鎖。而且有兩種意向鎖類型,分別為意向共享鎖和意向排他鎖

  1. 意向共享鎖(IS):是指在給一個數據行加共享鎖前必須先取得該表的IS鎖
  2. 意向排他鎖(IX):是指在給一個數據行加排他鎖前必須先取得該表的IX鎖

其實意向鎖的作用跟MDL鎖類似,都是防止在事務進行過程中,執行DDL語句的操作而導致數據不一致

InnoDB行鎖種類

在默認的事務隔離級別為RR,并且參數 innodb_locks_unsafe_for_binlog = 0 的模式下,行鎖的種類有三種

  1. 單個行記錄鎖(record lock):鎖定一個行記錄

注:主鍵和唯一索引都是行記錄的鎖模式。在RC隔離級別下,只有 record lock 記錄鎖模式

  1. 間隙鎖(gap lock):鎖定一個區間
  2. 記錄鎖和間隙鎖的組合叫做 next-key lock:鎖定行記錄 + 區間

注:普通索引默認的就是 next-key lock模式

單個行記錄的鎖
-- 查看索引
show index from dept_table;

company 字段有索引

事務A事務B
begin;begin;
update score_table set name = 'a' where score= 60;
update score_table set name = 'aaa' where score= 60; -- 出現鎖等待
update score_table set name = 'bbb' where score= 70; -- 正常更新
commit;
commit;

company 字段無索引

事務A事務B
begin;begin;
update score_table set name = 'a' where score= 60;
update score_table set name = 'bbb' where score= 70; -- 出現鎖等待
commit;
commit;

InnoDB的鎖是加在索引上的

間隙鎖

在RR事務隔離級別,為了避免幻讀現象,引入了 gap lock,但它只鎖定記錄的范圍,不包含記錄本身,即不允許在次范圍內插入任何數據

事務隔離級別RR

事務A事務B
begin;begin;
select * from score_table where score < 80 lock in share mode;
insert into score_table(name, score) values ('dd', 75); -- 等待
commit;
commit;

事務隔離級別RC

-- 查看事務隔離級別
show variables like '%tx_isolation%';
事務A事務B
begin;begin;
set session transaction isolation level read committed;set session transaction isolation level read committed;
select * from score_table where score < 80 lock in share mode;
insert into score_table(name, score) values ('dd', 75); -- 可提交
commit;
commit;

證明間隙鎖只是針對RR隔離級別才管用,從鎖的角度避免了幻讀發生

next-key locks

記錄鎖與間隙鎖的組合,當InnoDB掃描表記錄時,會先對選中的索引加上記錄鎖,再對索引記錄兩邊的間隙加上間隙鎖

事務A事務B
begin;begin;
select * from score_table where score < 85 for update;
insert into score_table(name, score) values ('dd', 85); -- 等待
commit;
commit;

證明不光鎖定 score < 85 這個區間的數據,還包含 85 這個值的本身

鎖等待和死鎖

鎖等待是指一個事務過程中產生的鎖,其他事務需要等待上一個事務釋放它的鎖,才能占用該資源。如果該事務一直不釋放,就需要持續等待下去,直到超過鎖等待時間,會報一個等待超時的錯誤

-- 查詢鎖等待時間
show variables like '%innodb_lock_wait%';-- 修改全局變量方式
set global innodb_lock_wait_timeout = 2;set @@global.innodb_lock_wait_timeout = 5;-- 修改當前事務變量方式
set innodb_lock_wait_timeout = 2;

死鎖是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,即事務1鎖住數據D1,正請求對D2加鎖,而事務2鎖住了D2,正請求加鎖D1,這樣就會導致死鎖

事務A事務B
begin;begin;
update score_table set name = 'a' where score= 60;
update score_table set name = 'bbb' where score= 70;
update score_table set name = 'b' where score= 70;
update score_table set name = 'aaa' where score= 60;
commit;
commit;
-- 查看死鎖展示信息
show engine innodb status;
解決死鎖
  1. 如果不同程序并發存取多個表,或者涉及多行記錄時,盡量約定以相同的順序訪問表,可以大大降低死鎖的機會
  2. 業務中盡量采用小事務,避免使用大事務,要及時提交或者回滾事務,可減少死鎖產生概率
  3. 在同一個事務中,盡可能做到一次鎖定所需要的所有資源,減少死鎖產生概率
  4. 對于非常容易產生死鎖的業務部分,可以嘗試使用升級鎖粒度,通過表鎖定來減少死鎖產生概率

四、索引

理解索引

在工作中,開發人員在開發初期由于多種原因設計表的過程中,沒有給后面可能會經常訪問的字段增加索引這個概念,由于后期的業務調整需求變更且數據也在不斷增長,會根據某些已存在的字段作為條件查詢。后面再增加索引會很麻煩,需要考慮現有系統的可用性,還需要考慮到當前增加索引列的內容。所以創建索引需要結合現有業務還要預知后期可能存在的業務變更,使設計的數據表伸縮性更強,在設計初期把數據表設計完善也能夠讓后面的開發事半功倍。

索引利用好了就是一輛”法拉利“,利用不好就成了”三輪車“了。

索引是什么?為什么要使用索引?

幫助MySQL做高效查詢的一種數據結構,好比是一本書的目錄,通過目錄能快速找到要查看的內容

提高查詢效率

索引分類

從存儲結構劃分:BTree索引(B-Tree或B+Tree索引),Hash索引

從應用層劃分:主鍵索引,唯一索引,普通索引,復合索引,全文索引,SPATIAL

根據鍵值的邏輯順序和表數據行的物理存儲順序:聚集索引,非聚集索引

聚集索引:葉子節點存放表中所有行數據記錄的信息

非聚集索引:不是聚集索引就是非聚集索引

索引何時無效?

索引一般在 where,order by,group by,表連接的條件列起作用

索引無效:

-- 1. 查詢條件的值是null
explain select * from dept_table where name = null;-- 2. NOT條件 比如:<>、in、not in、exists、not exists
explain select * from dept_table where name <> '新部門';explain select * from dept_table where name in ('財務部2'); -- 可以使用索引explain select * from dept_table where name in ('財務部2', '新部門'); -- 不使用索引explain select * from dept_table where name not in ('新部門'); -- 一個和多個都不使用索引explain select * from dept_table where exists (select * from dept_table where name = '新部門');explain select * from dept_table where not exists (select * from dept_table where name = '新部門');-- 3. LIKE通配符在前面
explain select * from dept_table where name like '%部門';explain select * from dept_table where name like '部門%'; -- 可以使用索引explain select * from dept_table where name like '新%門%'; -- 可以使用索引-- 4. 條件列上包括函數
explain select * from dept_table where upper(name) = 'NEW';explain select * from dept_table where name = upper('new'); -- 可以使用索引
索引存到哪里了?用什么方式存儲?

1072053-20190801111006066-1268954430.png

索引是存儲到磁盤上的文件

MyISAM引擎和InnoDB引擎共有文件

.frm文件:在MYSQL中建立任何一張數據表,在其數據目錄對應的數據庫目錄下都有對應表的.frm文件,.frm文件是用來保存每個數據表的元數據(meta)信息,包括表結構的定義等,.frm文件跟數據庫存儲引擎無關,也就是任何存儲引擎的數據表都必須有.frm文件,命名方式為數據表名.frm,如user.frm. .frm文件可以用來在數據庫崩潰時恢復表結構

InnoDB引擎文件

.ibd文件:單表表空間文件,每個表使用一個表空間文件(file per table),存放用戶數據庫表數據和索引

MyISAM引擎

.MYD:即 my data,表數據文件

.MYI:即 my index,索引文件

索引原理

MySQL為什么沒有使用二叉樹或紅黑樹?

推薦一個數據結構網站:www.cs.usfca.edu/~galles/visualization/Algorithms.html

如有 3、1、2、10、9、0、4、6這8個數據

哈希結構

  • 直接查詢:現在要從8個數中查找6這條記錄,只需要計算6的哈希值,便可快速定位記錄,時間復雜度為O(1)
  • 范圍查詢:如果要進行范圍查詢(大于4的數據),那這個索引就完全沒用了

1072053-20190801111038838-1529094778.png

二叉樹結構(右子樹大于左子樹)

  • 直接查詢:現在要從8個數中查找10這條記錄,先查找3,6>3,查找10,查找兩次就可以了
  • 范圍查詢:如果要進行范圍查詢(大于3的數據),直接查詢大于3的右子樹就行了

1072053-20190801111050663-66451665.png

不使用二叉樹原因:如果索引列查入的數據是單邊增長的,會導致查詢時依舊變慢,最差情況時間復雜度會變成O(N)

1072053-20190801111105898-364601086.png

紅黑樹結構(是一種平衡的二叉查找樹)

特點:

  1. 根節點是黑色
  2. 節點是紅色或者黑色
  3. 每個葉子節點都是黑色的空節點(null)
  4. 每個紅色節點的兩個子節點都是黑色的
  5. 從任意節點到其每個葉子的所有路徑都包含相同數量的黑色節點
  • 直接查詢:現在要從10個數中查找10這條記錄,先查找4,10>4,查找6,10>6,查找到8,10>8,查找到9,10>9,查找到10
  • 范圍查詢:如果要進行范圍查詢(大于6的數據),直接查詢大于6的右子樹就行了
  • 問題:當數據量變大后,樹的高度依然是很大,讀取I/O磁盤次數還是很多

1072053-20190801111120180-287716544.png

為什么想要減少磁盤I/O次數?

MySQL的數據實際是存儲在文件中,而磁盤IO的查找速度是要遠小于內存速度的,所以減少磁盤IO的次數能很大程度的提高MySQL性能

磁盤I/O為什么慢?

磁盤IO時間 = 尋道 + 磁盤旋轉 + 數據傳輸時間

從磁盤讀取數據時,系統會將邏輯地址發給磁盤,磁盤將邏輯地址轉換為物理地址(哪個磁道,哪個扇區)。 磁頭進行機械運動,先找到相應磁道,再找該磁道的對應扇區,扇區是磁盤的最小存儲單元

1072053-20190801111132526-565063911.png

性能對比

機械硬盤的連續讀寫性能很好,但隨機讀寫性能很差。

  • 順序訪問:內存訪問速度是硬盤訪問速度的6~7倍
  • 隨機訪問:內存訪問速度就要比硬盤訪問速度快上10萬倍以上

隨機讀寫時,磁頭需要不停的移動,時間都浪費在了磁頭尋址上。 而在實際的磁盤存儲里,是很少順序存儲的,因為這樣的維護成本會很高

局部性原理與磁盤預讀

由于存儲介質的特性,磁盤本身存取就比主存慢很多,再加上機械運動耗費,磁盤的存取速度往往是主存的幾百分分之一,因此為了提高效率,要盡量減少磁盤I/O。為了達到這個目的,磁盤往往不是嚴格按需讀取,而是每次都會預讀,即使只需要一個字節,磁盤也會從這個位置開始,順序向后讀取一定長度的數據放入內存。這樣做的理論依據是計算機科學中著名的局部性原理:

當一個數據被用到時,其附近的數據也通常會馬上被使用。

程序運行期間所需要的數據通常比較集中。

由于磁盤順序讀取的效率很高(不需要尋道時間,只需很少的旋轉時間),因此對于具有局部性的程序來說,預讀可以提高I/O效率。

預讀的長度一般為頁(page)的整倍數。頁是計算機管理存儲器的邏輯塊,硬件及操作系統往往將主存和磁盤存儲區分割為連續的大小相等的塊,每個存儲塊稱為一頁(在許多操作系統中,頁得大小通常為4k),主存和磁盤以頁為單位交換數據。當程序要讀取的數據不在主存中時,會觸發一個缺頁異常,此時系統會向磁盤發出讀盤信號,磁盤會找到數據的起始位置并向后連續讀取一頁或幾頁載入內存中,然后異常返回,程序繼續運行。

BTree(B-Tree)和B+Tree閃亮登場

度(m):節點數據存儲個數

深度關系(h):h=log(m+1)N

1072053-20190801111149165-2137103270.png

1072053-20190801111159068-334728916.png

B+Tree相對于BTree區別:

  1. 非葉子節點只存儲索引鍵,從而降低B+樹的高度,進而減少IO次數
  2. 葉子節點存儲整張表的所有行數
MyISAM索引實現

MyISAM引擎使用B+Tree作為索引結構,葉節點的data域存放的是數據記錄的地址

1072053-20190801111225744-1581550400.png

這里設表一共有三列,假設我們以Col1為主鍵,上圖是一個MyISAM表的主索引(Primary key)示意。可以看出MyISAM的索引文件僅僅保存數據記錄的地址。在MyISAM中,主索引和輔助索引(Secondary key)在結構上沒有任何區別,只是主索引要求key是唯一的,而輔助索引的key可以重復。如果我們在Col2上建立一個輔助索引,則此索引的結構如下圖所示

1072053-20190801111311056-121299687.png

同樣也是一顆B+Tree,data域保存數據記錄的地址。因此,MyISAM中索引檢索的算法為首先按照B+Tree搜索算法搜索索引,如果指定的Key存在,則取出其data域的值,然后以data域的值為地址,讀取相應數據記錄

所以MyISAM是非“聚集索引”,從索引文件和數據文件分別存儲就可以看出。也與下面介紹的InnoDB的“聚集索引”做區分

InnoDB索引實現

雖然InnoDB也使用B+Tree作為索引結構,但具體實現方式卻與MyISAM截然不同

第一個不同:MyISAM索引文件和數據文件是分離的,索引文件僅保存數據記錄的地址。InnoDB的數據文件本身就是索引文件,從文件存儲上就可以知道,表數據文件本身就是按B+Tree組織的一個索引結構,這棵樹的葉節點data域保存了完整的數據記錄。這個索引的key是數據表的主鍵,因此InnoDB表數據文件本身就是主索引

1072053-20190801111327807-1384858249.png
? InnoDB主索引(同時也是數據文件)的示意圖

可以看到葉節點包含了完整的數據記錄。這種索引叫做聚集索引。因為InnoDB的數據文件本身要按主鍵聚集,所以InnoDB要求表必須有主鍵(MyISAM可以沒有),如果沒有顯式指定,則MySQL系統會自動選擇一個可以唯一標識數據記錄的列作為主鍵,如果不存在這種列,則MySQL自動為InnoDB表生成一個隱含字段作為主鍵,這個字段長度為6個字節,類型為長整形。

第二個不同:與MyISAM索引的不同是InnoDB的輔助索引data域存儲相應記錄主鍵的值而不是地址。換句話說,InnoDB的所有輔助索引都引用主鍵作為data域

1072053-20190801111339678-1665402441.png
? InnoDB輔助索引(輔助索引獲得主鍵索引)的示意圖

這里以英文字符的ASCII碼作為比較準則。聚集索引這種實現方式使得按主鍵的搜索十分高效,但是輔助索引搜索需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄。

問題
  1. InnoDB引擎為什么必須有主鍵且建議使用整型自增主鍵?

空間方面:uuid存儲空間更大

比較關系:索引之間有比較關系,整型的比較會更快

結構方面(最重要一點):使用自增主鍵保證插入數據都是向葉子節點后面順序插入,如果使用uuid比較,生成的uuid不一定順序插入,導致插入到節點的中間位置,如果該節點已經滿了,會導致節點進行分裂變成新的結構

  1. 為什么InnoDB引擎的非主鍵索引數據存儲的是主鍵值?

一致性和節省存儲空間

  1. 節點的度設置為多少合適?

B-Tree節點的度設置等于一個頁,每次新建節點直接申請一個頁的空間,這樣就保證一個節點物理上也存儲在一個頁里,就實現了一個節點的載入只需要載入一次I/O

  1. 聯合索引的底層存儲結構是長什么樣?

1072053-20190801111407366-1675287512.png

四、總結

  1. 數據庫結構、一條SQL執行過程
  2. 事務隔離級別、并發問題、可重復讀的實現過程
  3. 鎖的使用、鎖等待、死鎖
  4. 索引分類、索引如何存儲、索引何時無效、MySQL為什么使用B+Tree作為索引結構、MyISAM索引實現、InnoDB索引實現
  5. 磁盤讀寫過程
  6. MySQL主從復制過程

五、主從復制

事務相關的重要日志

1072053-20190801111423150-1900533114.png

redolog:數據日志

undolog:ibdata1

binlog:邏輯日志

posted on 2019-08-01 11:06?小猴子先生 閱讀(...) 評論(...) 編輯 收藏

轉載于:https://www.cnblogs.com/guoyinli/p/11281251.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/276972.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/276972.shtml
英文地址,請注明出處:http://en.pswp.cn/news/276972.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

IDEA 實用功能Auto Import:自動優化導包(自動刪除、導入包)

JetBrains公司的intellij Idea堪稱JAVA編程界的蘋果&#xff0c;用戶體驗非常好 下面介紹一下IDEA的一個能顯著提升寫代碼效率的非常好用的功能設置—— Auto Import Auto Import的功能是可以幫助我們自動刪除無用的包Import(未被引用)&#xff0c;以及自動Import填充尚未導入的…

怎么看網站是否被黑防止網站被黑

2019獨角獸企業重金招聘Python工程師標準>>> 網站被黑&#xff0c;打開網站竟然跳轉到博cai網站上去了&#xff0c;一開始以為自己看錯了&#xff0c;多次從百度點擊自己網站進去&#xff0c;還是會跳轉到彩piao網站上&#xff0c;第一反應是自己的網站被黑了&#…

c#事務的使用、示例及注意事項

一、事務的介紹.NET Framework 開發員指南事務是一組組合成邏輯工作單元的操作&#xff0c;雖然系統中可能會出錯&#xff0c;但事務將控制和維護事務中每個操作的一致性和完整性。例如&#xff0c;在將資金從一個帳戶轉移到另一個帳戶的銀行應用中&#xff0c;一個帳戶將一定的…

鏡像服務器文件實時監控同步程序

這是為我們網站解決南北電信網通互聯互通問題而寫的一個程序。 優游中國(www.yooyocn.com)是一個大型旅游門戶網站&#xff0c;提供了資訊&#xff0c;視頻&#xff0c;圖片&#xff0c;博客&#xff0c;論壇等大數據量的業務內容。 為了使全國各地的網友都能夠快速訪問我們的網…

Nginx學習系列二Linux下Nginx實現負載均衡

關于在本地虛擬機(VMware 14)下安裝Linux同時安裝Nginx,請參考Nginx學習系列之搭建環境 1、啟動Nginx 在Nginx安裝成功的前提下,啟動Nginx 已root模式登陸(權限需要),接著找到Nginx的安裝目錄,啟動Nginx,并且指定Nginx啟動所需的配置文件,該文件也在Nginx的安裝目錄下. 2、查看…

FastCGI中文規范

http://fuzhong1983.blog.163.com/blog/static/1684705201051002951763/ . 介紹 FastCGI是對CGI的開放的擴展&#xff0c;它為所有因特網應用提供高性能&#xff0c;且沒有Web服務器API的缺點&#xff08;penalty&#xff09;。 本規范具有有限的&#xff08;narrow&#xff09…

設計模式初學者系列-策略模式 -------為什么總是繼承

設計模式初學者系列&#xff0d;策略模式 -------為什么總是繼承 模板方法的延續 這篇稿子是基于我的前一篇模板方法設計模式之上演繹的&#xff0c;如果沒有閱讀請點擊這里查看&#xff0c;以了解這篇稿子的上下文。 在模板方法設計模式里我舉了一個例子&#xff1a;教育部…

紅米airdots掉了怎么查找_紅米K30 Pro 榮耀V30pro 這兩款手機該怎么選呢?

點擊?玩機數碼君?關注我&#xff0c;加★星標★你好 我是歲月神偷昨天可以說是小米拍手稱快的一天&#xff0c;紅米K30 Pro以2999的超低價成為目前最便宜的驍龍865旗艦&#xff0c;讓友商拍馬難追。友商明眼人都知道說的華為&#xff0c;怎么感覺小米每次發布會也替華為宣傳了…

返回一個循環整數組最大子數組和

任務要求&#xff1a; 1、輸入一個整形數組&#xff0c;數組里有正數也有負數。 2、數組中連續的一個或多個整數組成一個子數組&#xff0c;每個子數組都有一個和。 3、如果數組A[0]……A[j-1]首尾相鄰&#xff0c;允許A[i-1]&#xff0c; …… A[n-1]&#xff0c; A[0]……A…

中文分詞入門之字標注法4

http://www.52nlp.cn/%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D%E5%85%A5%E9%97%A8%E4%B9%8B%E5%AD%97%E6%A0%87%E6%B3%A8%E6%B3%954 上一節主要介紹的是利用最大熵工具包來做字標注中文分詞&#xff0c;這一節我們直奔主題&#xff0c;借用條件隨機場工具“CRF: Yet Another CRF …

后臺設置 datakeynames

FormView2.DataKeyNames new String[] { "ShoppingRemarkID" }; 轉載于:https://www.cnblogs.com/Fernando/archive/2008/01/16/1041717.html

4K 海思 聯詠 芯片_老電視也有春天,換裝海美迪4K電視盒子H7 Plus

寫在前面YALL&#xff0c;大家好&#xff0c;我是老炮兒許老板。疫情進入六月逐漸好轉&#xff0c;各級各類學校相繼開學&#xff0c;年前給兒子報的托班也終于迎來了開學&#xff0c;平日里幫忙照看兒子的爺爺奶奶也終于得到了解放。現在白天有大把大把的時間來追劇看電視&…

知識付費不熱了,得到們接下來故事怎么講?

如今&#xff0c;知識付費風口已過&#xff0c;紅利期隨之在逐漸消失&#xff0c;很多知識付費的創業者也在感嘆生意難做&#xff0c;甚至有人已經開始離場。比如&#xff0c;百度音頻知識付費產品只生存了6個月&#xff0c;最后的更新時間則停在7月13日。再如&#xff0c;在分…

I'm genius,用游戲柄控制鼠標

昨天不小心把鼠標放在店里沒有帶回來&#xff0c;今天電腦就沒有鼠標了&#xff0c;用了很久的鍵盤&#xff0c;實在不爽&#xff0c;就突然發現自己有一個游戲柄&#xff0c;后來到網上查了一下怎么用游戲柄控制鼠標&#xff0c;呵呵&#xff0c;發現了一個&#xff0c;下載用…

WCF從理論到實踐(4):路在何方

本文的出發點 通過閱讀本文&#xff0c;您能了解以下知識&#xff1a; Address是什么&#xff1f; Address的組成&#xff1f; 如何在配置文件中指定Address? 如何通過編程方式設置Address? Address有什么特殊應用&#xff1f; 本文適合的讀者 適合WCF初學者&#xff…

office 2007圖標_微軟Office 365桌面版新圖標開始測試

IT之家3月1日消息 此前&#xff0c;微軟公布了全新的Office圖標&#xff0c;微軟Office 365在線網頁版在2月15日開始已經全面更新新版圖標&#xff0c;而桌面版Office 365現在也陸續開始測試新版圖標。目前微軟Office Dogfood通道上推送的開發者預覽版本已經在2月27日開始測試O…

【動態規劃BFS】相遇

這是我第一次模擬題測試點全部AC。。。 同機房的DALAO都用的BFS 然而我用的DP&#xff08;其實不會BFS&#xff09; 話不多說&#xff0c;上題&#xff01; &#xff08;灰常詳細&#xff09;DP解法&#xff1a; 重點還是狀態轉移方程式的推導 1個點i要么是后面的位置i-1往前走…

Ruby on Rails 通過代理遠程安裝

在網上查了一些資料&#xff0c;都不詳細&#xff0c;現在列出標準命令&#xff1a; 1。如果代理服務器需要認證 gem install rails --include-dependencies --http-proxy http://username:passwordproxy:port 2。如果代理服務器不需要認證 gem install rails --include-depend…

五個思路,教你如何建立金融業的數據分析管理模型

說起銀行、保險、股票投資這樣的金融行業&#xff0c;很多人都認為它們是依靠數據驅動的企業&#xff0c;畢竟大數據的誕生本來就是為了金融信息流通而服務的&#xff0c;但在我身邊很多搞證券、投資的朋友看來&#xff0c;事實卻并非如此。 真正在金融行業做數據分析的人&…

【SSH網上商城項目實戰19】訂單信息的級聯入庫以及頁面的緩存問題

購物車這一塊還剩最后兩個問題&#xff0c;就是訂單信息的級聯入庫和頁面緩存&#xff0c;這里的信息是指購物車和購物項&#xff0c;即我們將購物車的信息存入數據庫的同時&#xff0c;也存入每個購物項的信息&#xff0c;而且外鍵都關聯好&#xff0c;這涉及到了Hibernate中的…