簡體   English   中英

在 AUTO_INCREMENT 列中使用 UNIQUE 來創建改進的 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM