InnoDB 的表結構

InnoDB是索引組織表,這種結構的存儲是根據主鍵順序組織的。InnoDB要求每張表都必須有一個主鍵,如果沒有InnoDB會自己確定或添加一個主鍵

InnoDB的主鍵索引也稱爲聚集索引,是一個核心的索引,聚集索引採用B+ 樹結構,每個索引項都包含了row數據,也就是通過索引可以定義到具體的row數據,無需二次IO。

索引組織表的主鍵確定

主鍵是索引組織表的核心,表數據按照主鍵順序存儲,InnoDB的主鍵確定過程如下:

  • 絕大部分表都顯示指定(已經做了要求),而且指定爲自增類型;
  • 如果沒有指定,則查找有沒有非null的unique索引,如果有,則該column爲primary key;
  • 如果找到了多個not null unique index,則使用第一個,這個順序是index的定義順序不是table的定義順序;
  • 如果不符合,則自動創建一個6字節大小的指針作爲主鍵:_rowId;

組成

InnoDB基於表空間、段、區、頁、行來組織數據。一個表空間包含多個段,每個段存儲了不同類型的數據,如數據段、索引段。每個段由多個區構成,每個區有多個頁,頁是內存池中的基本管理單位,也是索引的基本單位,每個頁包含多個行,行就是數據和核心。

  • 表空間:tablespace是數據的頂級組織和存放區域,存儲了各種信息,數據,索引,事務信息等;
  • 段:segment可以分爲數據段、索引段、回滾段,數據段是B+樹的葉子節點,索引段是B+樹的非葉子節點;
  • 區:extent 區的大小固定1M;
  • 頁:page 默認16KB,1個區有64個page,
  • 行:row InnoDB的數據是按row存放(相比hive 按照column存放,導致二者差異性),每頁最多存儲79992行。

Varchar和char字段

由於InnoDB 數據行的存儲格式的特點,InnoDB支持的Varchar最大爲65535字節,但是由於還需要存儲其他元信息,實際上varchar最大爲65532字節,而且65535是所有varchar字段的總和,如果總和超過了該大小,需要使用text或者blob,某些sql級別下innoDB會自動轉換。

還有就是如果每頁數據存放不了2 row數據,則會出現行溢出現象,數據溢出會增大磁盤IO,所以varchar字段的總長度不要超過8098。

如果varchar太長,InnoDB創建時會使用text或者blob替換,但是text、blob類似指針方式存儲,這也會加大磁盤IO,效率會下降。

char字段的單位是字符,表象上是固定長度,但是存儲時也是一種另類的varchar,varchar的單位是字節,要注意區別,也就是char(2)在不同字符集下,ab和‘我們’都是一樣存儲的。

約束

約束是數據庫的重要特徵,InnoDB支持如下幾種約束方式:

  • 類型約束:使用合適的數據類型,如int類型不能存儲string;
  • 唯一約束:定義primary key或者unique index;
  • 外鍵約束:定義foregin key;
  • enum和set約束;
  • 使用觸發器或者defalut來約束默認值;

約束的建立方式:

  • private key;
  • unique key;
  • foregin key;
  • not null;
  • defalut;

SQL 語句

create table xx (
    aa int defalut 1,
    bb varchar(800) not null,
    'sex' enum('1','0'),#不建議使用
    uniquey key(bb) , 
    primary key (aa)
)engine = innodb;

alert table xx add unique key idx_xx(aa);

crete index idx_xx on xx (aa);

create unique index idx_xx on xx (aa);

# 觸發器 trigger
create trigger tr_aa {before|after insert|update|delete}
on xx for each row BEGIN
....
END

PS :

創建約束的同時基本上就等於創建了索引,但是索引更偏向物理上、性能上的優化,約束是邏輯上、業務上的完整性;

* 約束並不一定報錯,要設置sql_mode 爲 strict_trans_tables;*

* 每個表最多建立6個觸發器 *

MyISAM不支持外鍵和事務。

分區

InnoDB和MyISAM、NDB都可以支持分區,但是有些存儲引擎是不支持的。分區操作常見於程序性分區,數據庫僅僅支持水平分區,不支持垂直分區。

垂直拆分:按照column拆分,拆分熱點字段。

mysql僅僅支持局部分區,也就是數據、索引在一起,不支持全局分區,全局分區要求,數據分開,但是索引不分開。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章