一、索引組織表
在InnoDB中存儲引擎中,表都是根據主鍵索引順序組織存放的,這種存儲方式稱爲索引組織表。
其中每張表都有個主鍵,如果在表創建的時候沒有指定,那麼InnoDB將按照下面方式進行創建。
1、首先判斷是否有非空唯一索引(Unique NOT NULL ),如果有就選擇其爲主鍵。如果有多個非空唯一索引,那麼就根據定義所以的順序選擇主鍵。就是哪個唯一索引先被定義哪個就成爲主鍵。
2、如果都不存在,就自動創建一個6字節大小的指針。
二、InnoDB邏輯存儲結構
InnoDB的邏輯存儲結構稱之爲表空間(tablespace)。表空間又由段(segment)、區(extent)、頁(page)組成。如圖:
1、表空間
表空間是InnoDB邏輯結構的最高層,所有數據都在其中,默認情況下就是ibdata1。如果開啓了innodb_file_per_table這個參數,那就每張表內的數據就是一個單獨的表空間。
但是,就算開啓了innodb_file_per_table參數,每張表空間存放的只是數據、索引和插入緩衝Bitmap頁,其他的如回滾(undo)信息、插入緩衝索引頁、系統事物信息、二次寫緩衝(Double write buffer)還是放在原來的共享表空間中(ibdata1)。
2、段
表空間是由段組成的,常見有數據段、索引段、回滾段等。因爲InnoDB存儲引擎是索引組織的,因此數據即索引,索引即數據。如邏輯架構圖數據段就是B+樹的葉子節點(Leaf node segment),索引段就是B+樹的非索引節點(Non-Leaf node segment)。
3、區
記住幾個重要概念,區是由連續的頁組成的,在任何情況下每個區大小都是1M。爲了保證區中頁的連續性,引擎一般一次從磁盤申請4~5個區。默認情況下每個頁爲16k,所以每個區有64個連續頁。 InnoDB 1.2.x後可以通過innodb_file_per_table參數修改默認頁大小,但是不怎麼變,區的大小永遠是1M。
4、頁
頁是InnoDB磁盤管理的最小單位,默認大小爲16k, 常見的頁類型如下:
- 數據頁(B-tree Node)
就是用來存放我們真實數據的,在聚集索引上的葉子結點稱爲數據頁,每個數據頁通過一個雙向鏈表連接。 - undo 頁(undo Log Page)
undo log 是回滾日誌,提供回滾操作。雖然他和redo log 都是事物日誌,但是redo log通常事物裏日誌,記錄數據頁的物理修改,恢復數據頁只能恢復最後一次提交位置。undo log 是邏輯日誌,根據每行變更進行記錄,可以回滾行記錄的某個版本。 - 系統頁(System Page)
- 事物數據頁(Transaction system page)
- 插入緩衝位圖頁(Insert Buffer Bitmap)
- 插入緩衝空閒列表(Insert Buffer Free List)
- 未壓縮的二進制大對象頁(Uncompressed BLOB Page)
- 壓縮的二進制大對象頁(compressed BLOB Page)
5、行
InnoDB是面向列的,也就是說數據是按照行進行存儲的。每頁存放的行記錄最多爲16K/2-200行,也就是7992行記錄。
6、約束
實體完整性是保證表中有一個主鍵。在InnoDB中,用戶可以通過定義Primary Key 或 Unique Key 約束來保證實體完整性。還可以編寫一個觸發器來保證實體完整性。
InnoDB 提供以下約束:
- Primary Key 是一個列或者列的組合,其值能夠唯一的標識表中每一行,每個表只能有一個主鍵,且不能爲NULL。
- Unique Key 允許爲空,但只能出現一個空值,唯一約束能保證一個列或者幾列不出現重複值
- Foreign Key 用於兩個表關係的建立
- Default 默認值約束,比如性別列,如果插入沒賦值就默認爲 女
- NOT NULL 非空約束,代表此列不能爲空
約束創建形式:
- 表創建時進行約束定義
- 利用ALERT TABLE 命令來創建約束
- 對於Unique Key(唯一索引) 的約束,可以通過CREATE UNIQUE INDEX進行創建,默認約束名稱和列名稱一樣。
- 對於主鍵約束,默認約束名爲PRIMARY
UNIQUE 和 PRIMARY KEY 的區別:一個表可以有多個字段聲明爲
UNIQUE,但只能有一個 PRIMARY KEY 聲明;聲明爲 PRIMAY KEY 的列不允許有空值,但是聲明爲 UNIQUE 的字段允許空值的存在。
約束和索引的區別
用戶創建了一個唯一索引,就是創建了一個唯一約束。但約束是一個邏輯概念,用來保證數據完整性,而索引是一個數據結構,既有邏輯概念,還代表了物理存儲方式。
7、視圖
視圖是一個命名的虛表,它由一個查詢SQL來定義。與持久表不同的是,視圖中的數據沒有實際的物理存儲。
8、分區表
分區功能並不是在存儲引擎層完成的,所以用的時候需要選擇支持的存儲引擎,InnoDB 、MyISAM 都支持。分區過程,是將一個表或索引分解爲多個更小、更方便管理的部分。分區功能只支持水平分區(將同一表的不同行分配到不同的物理文件中),不支持垂直分區(將同一表中中的不同列,分配到不同物理文件中),當前MySQL不支持全局分區。
當前MYSQL支持的分區類型:
- RANGE分區:根據一個連續的列值進行數據分區。比如自增id ,0-50W 、50-100w分倆區。
- LIST分區:和RANGE類似,只是LIST分區面向的是離散值。
- HASH分區:根據用戶自定義的表達式的返回值進行分區,返回值不能爲負。
- KEY分區:根據MYSQL數據庫提供的哈希函數進行分區。
不論哪種分區,如表中存在主鍵或唯一索引,分區列必須是唯一索引的一個組成部分。如果建表時沒有指定唯一索引或主鍵,則可以知道任何一個列作爲分區列。
子分區概念:子分區是在分區的基礎上再進行分區,也稱爲複合分區。