1. 程式人生 > >【MySQL技術內幕】16-索引組織表

【MySQL技術內幕】16-索引組織表

在 InnoDB儲存引擎中,表都是根據主鍵順序組織存放的,這種儲存方式的表稱為索引組織表( index organized table)。在 InnoDB儲存引擎表中,每張表都有個主鍵( Primary Key),如果在建立表時沒有顯式地定義主鍵,則 InnoDB儲存引擎會按如下方式選擇或建立主鍵:

  • 首先判斷表中是否有非空的唯一索引( Unique NOT NULL),如果有,則該列即為主鍵。
  • 如果不符合上述條件, InnoDB儲存引擎自動建立一個6位元組大小的指標。

當表中有多個非空唯一索引時, InnoDB儲存引擎將選擇建表時第一個定義的非空唯一索引為主鍵。這裡需要非常注意的是,主鍵的選擇根據的是定義索引的順序,而不是建表時列的順序。看下面的例子:

mysql> create table z( a int not null, b int null, c int not null, d int not null, unique key(b), unique key(d), unique key(c) );
Query OK, 0 rows affected (0.03 sec)

mysql> insert into z select 1,2,3,4;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> insert into z select 5,6,7,8;
Query OK, 1 row affected (0.01 sec)
Records: 1  Duplicates: 0  Warnings: 0

上述示例建立了一張表z,有a、b、c、d四個列。b、c、d三列上都有唯一索引,不同的是b列允許NULL值。由於沒有顯式地定義主鍵,因此會選擇非空的唯一索引,可以通過下面的SQL語句判斷表的主鍵值:

mysql> select a,b,c,d,_rowid from z;
+---+------+---+---+--------+
| a | b    | c | d | _rowid |
+---+------+---+---+--------+
| 1 |    2 | 3 | 4 |      4 |
| 5 |    6 | 7 | 8 |      8 |
+---+------+---+---+--------+
2 rows in set (0.01 sec)

_rowid可以顯示錶的主鍵,因此通過上述查詢可以找到表z的主鍵。此外,雖然c,d列都是非空唯一索引,都可以作為主鍵的候選,但是在定義的過程中,由於d列首先定義為唯一索引,故 InnodB儲存引擎將其視為主鍵。 另外需要注意的是, rowid只能用於檢視單個列為主鍵的情況,對於多列組成的主鍵就顯得無能為力了,如:

mysql> CREATE TABLE a(
    -> a Int,
    -> b Int,
    -> PRIMARY KEY(a, b)
    -> )ENGINE=InnodB;
ERROR 1050 (42S01): Table 'a' already exists
mysql> insert into a select 1,1;
Query OK, 1 row affected (0.00 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> select a, _rowid FROM a;
ERROR 1054 (42S22): Unknown column '_rowid' in 'field list'