![](/img/trans.png)
[英]MySQL defining column as UNIQUE with AUTO_INCREMENT instead of as Primary Key
[英]Use UNIQUE in AUTO_INCREMENT column to create an improved PRIMARY KEY
考慮到在 MySQL 中AUTO_INCREMENT
列必須是PRIMARY KEY
一部分,我想問一下在該AUTO_INCREMENT
列中使用UNIQUE
鍵是否能夠創建復合PRIMARY KEY
而不將其定義為第一個PK 索引是否有意義。
我創建了一個這樣的表:
CREATE TABLE `test` (
id INT NOT NULL auto_increment,
a INT NOT NULL,
b INT NOT NULL,
c INT NOT NULL,
PRIMARY KEY (id, a, b));
我的目的是按(a)
或(a, b)
,然后根據id
對其進行排序。 我想創建一個PRIMARY KEY
作為(a, b, id)
但定義不允許。 此外,由於文檔狀態,一個PRIMARY KEY
組成(x, y, z)
將利用PRIMARY KEY
只有當你通過搜索(x)
(x, y)
或(x, y, z)
但如果您通過(y)
或(y , z)
(或其他任何內容)進行搜索。 我驗證過了。 事實上,根據上述PRIMARY KEY (id, a, b)
定義,任何搜索a
查詢都不使用任何PRIMARY KEY
:
DESCRIBE SELECT `a`, `b` FROM `test` WHERE `a` = 0;
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
| 1 | SIMPLE | test | index | NULL | PRIMARY | 12 | NULL | 1 | Using where; Using index |
+------+-------------+-------+-------+---------------+---------+---------+------+------+--------------------------+
我決定作弊並將id
重新定義為UNIQUE KEY
(因此它仍然被視為KEY
),然后重新創建一個PRIMARY KEY
作為(a, b, id)
。 這有效:
ALTER TABLE `test` DROP PRIMARY KEY, ADD UNIQUE KEY (`id`), ADD PRIMARY KEY (`a`, `b`, `id`)
現在,按a
搜索使用PRIMARY KEY
!
DESCRIBE SELECT `a`, `b` FROM `test` WHERE `a` = 0;
+------+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
| 1 | SIMPLE | test | ref | PRIMARY | PRIMARY | 4 | const | 1 | Using index |
+------+-------------+-------+------+---------------+---------+---------+-------+------+-------------+
這會將id
在第一個位置的原始PRIMARY KEY (id, a, b)
更改為另一個在第一個位置具有a
方案:
# before
SHOW KEYS FROM `test`;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test | 0 | PRIMARY | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
| test | 0 | PRIMARY | 2 | a | A | 0 | NULL | NULL | | BTREE | | |
| test | 0 | PRIMARY | 3 | b | A | 0 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
# after
SHOW KEYS FROM `test`;
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| test | 0 | PRIMARY | 1 | a | A | 0 | NULL | NULL | | BTREE | | |
| test | 0 | PRIMARY | 2 | b | A | 0 | NULL | NULL | | BTREE | | |
| test | 0 | PRIMARY | 3 | id | A | 0 | NULL | NULL | | BTREE | | |
| test | 0 | id | 1 | id | A | 0 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
這是否有任何性能損失或我沒有看到的任何缺點? 這個解決方案在我看來比觸發存儲過程來增加索引更簡單(就像這個解決方案)。
先感謝您
似乎您可以通過將 id 作為唯一主鍵和 (a,b) 和 (a) 上的索引來實現您的目標 - 最近版本的 mysql 會隱式地將主鍵添加到所有其他索引的末尾。 為避免單獨的排序步驟,您可能需要提示 a= 查詢使用 a 索引而不是 a,b 索引。 如果 id 本身是唯一的,則沒有理由擁有更長的主鍵。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.