在MySQL中,当创建CREATE TABLE时,MySQL是否可以隐式创建一个列(即,在CREATE TABLE命令中未明确声明的列)作为表的主键?
谢谢。
答案 0 :(得分:3)
否,需要在表上定义PRIMARY KEY。
您可能正在考虑适用于InnoDB引擎的this:
如果表没有PRIMARY KEY或合适的UNIQUE索引,则为InnoDB 在内部生成名为GEN_CLUST_INDEX的隐藏的聚集索引 包含行ID值的合成列。行按以下顺序排序 InnoDB分配给此类表中的行的ID。行ID为 一个6字节的字段,随着插入新行而单调增加。 因此,按行ID排序的行实际上是插入的 订单。
下面是一个示例,该示例显示了没有主键和唯一列的表的索引创建。
# Create the table
create table test.check_table (id int, description varchar(10)) ENGINE = INNODB;
# Verify that there is no primary or unique column
desc test.check_table;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| description | varchar(10) | YES | | NULL | |
+-------------+-------------+------+-----+---------+-------+
# Insert some values
insert into test.check_table values(1, 'value-1');
insert into test.check_table values(2, 'value-2');
insert into test.check_table values(null, 'value-3');
insert into test.check_table values(4, null);
insert into test.check_table values(1, 'value-1');
# Verify table
select * from test.check_table;
+------+-------------+
| id | description |
+------+-------------+
| 1 | value-1 |
| 2 | value-2 |
| NULL | value-3 |
| 4 | NULL |
| 1 | value-1 |
+------+-------------+
# Verify that the GEN_CLUST_INDEX index is auto-created.
select * from INFORMATION_SCHEMA.INNODB_INDEX_STATS where TABLE_SCHEMA='test' and TABLE_NAME = 'check_table';
+--------------+-------------+-----------------+--------+--------------+-------------------+------------------+
| table_schema | table_name | index_name | fields | rows_per_key | index_total_pages | index_leaf_pages |
+--------------+-------------+-----------------+--------+--------------+-------------------+------------------+
| test | check_table | GEN_CLUST_INDEX | 1 | 5 | 1 | 1 |
+--------------+-------------+-----------------+--------+--------------+-------------------+------------------+
# Duplicate rows are still allowed (Primary Key constraints not enforced)
insert into test.check_table values(1, 'value-1');
select * from test.check_table;
+------+-------------+
| id | description |
+------+-------------+
| 1 | value-1 |
| 2 | value-2 |
| NULL | value-3 |
| 4 | NULL |
| 1 | value-1 |
| 5 | value-5 |
| 1 | value-1 |
+------+-------------+
相反,指定了PRIMARY KEY的表将创建一个名称为PRIMARY的索引。
# Create another table
create table test.check_table_2 (id int, description varchar(10), PRIMARY KEY(id)) ENGINE = INNODB;
# Verify primary key column
desc check_table_2;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | 0 | |
| description | varchar(10) | YES | | NULL | |
+-------------+-------------+------+-----+---------+-------+
# Verify index
select * from INFORMATION_SCHEMA.INNODB_INDEX_STATS where TABLE_SCHEMA='test' and TABLE_NAME = 'check_table_2';
+--------------+---------------+------------+--------+--------------+-------------------+------------------+
| table_schema | table_name | index_name | fields | rows_per_key | index_total_pages | index_leaf_pages |
+--------------+---------------+------------+--------+--------------+-------------------+------------------+
| test | check_table_2 | PRIMARY | 1 | 0 | 1 | 1 |
+--------------+---------------+------------+--------+--------------+-------------------+------------------+
# Primary key is enforced
insert into check_table_2 values(1,'value-1');
OK
insert into check_table_2 values(1,'value-1');
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'