四,primary key
關係型數據庫中的一條記錄中有若干個屬性,若其中某一個屬性組(注意是組)能唯一標識一條記錄,該屬性組就可以成爲一個主鍵。
例如
學生表(學號,姓名,性別,班級) 其中每個學生的學號是唯一的,學號就是一個主鍵,這叫單列主鍵
課程表(課程編號,課程名,學分) 其中課程編號是唯一的,課程編號就是一個主鍵,這叫單列主鍵成績
表(學號,課程號, 成績)成績表中唯一一個屬性無法唯一標識一條記錄,學號和課程號的組合纔可以唯一標識一條記錄,所以學號和課程號的屬性組是一個主鍵,這叫多列主鍵
成績表中的學號不是成績表的主鍵,但它和學生表中的學號相對應,並且學生表
中的學號是學生表的主鍵,則稱成績表中的學號是學生表的外鍵。
同理成績表中的課程號是課程表的外鍵 primary key關鍵字用於定義列爲主鍵。
單列主鍵
在某一個字段後用primary key
create table t6(
id int primary key,
name varchar(20),
number char(10));
desc t6;
執行結果爲:
mysql> create table t6( id int primary key, name varchar(20), number char(10));
Query OK, 0 rows affected (0.53 sec)
mysql> desc t6;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| number | char(10) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
在所有前端後單獨定義主鍵
create table t7 (
id int,
name varchar (20),
number char (10),
constraint pk_id primary key(id)); #創建主鍵併爲此命名
desc t7;
執行結果爲:
mysql> create table t7(
-> id int,
-> name varchar(20),
-> number varchar(20),
-> constraint pk_id primary key(id));
Query OK, 0 rows affected (0.68 sec)
mysql> desc t7;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(20) | YES | | NULL | |
| number | varchar(20) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
多列主鍵
mysql> create table t8(
-> student_number char(10),
-> class_number char(10),
-> achievement int not null default 0,
-> primary key(student_number, class_number));
Query OK, 0 rows affected (0.73 sec)
mysql> desc t8;
+----------------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+----------+------+-----+---------+-------+
| student_number | char(10) | NO | PRI | NULL | |
| class_number | char(10) | NO | PRI | NULL | |
| achievement | int(11) | NO | | 0 | |
+----------------+----------+------+-----+---------+-------+
3 rows in set (0.00 sec)
mysql> insert into t8 values
-> ("18023300", "186000", 100),
-> ("19205200", "192000", 90);
Query OK, 2 rows affected (0.18 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> insert into t8 values("18023300", "186000", 90);
ERROR 1062 (23000): Duplicate entry '18023300-186000' for key 'PRIMARY'
mysql> select * from t8;
+----------------+--------------+-------------+
| student_number | class_number | achievement |
+----------------+--------------+-------------+
| 18023300 | 186000 | 100 |
| 19205200 | 192000 | 90 |
+----------------+--------------+-------------+
2 rows in set (0.00 sec)
auto_increment
我們每次往表中插入數據的時候都得記住id,這樣非常考驗腦力,有的時候我們可能記得不是很清楚,那就容易報錯,使用auto_increment約束字段會自動增長,被約束的字段必須同時被key約束。
create table t9(
id int primary key auto_increment,
name varchar(20),
sex enum("male", "female"));
desc t9;
insert into t9(name) values("Alex"),("Coco");
select * from t9;
insert into t9 values(5, "BeiBei", "female");
select * from t9;
delete from t9;
select * from t9;
insert into t9(name, sex) values("Alex", "male"),("Coco", "female");
select * from t9;
truncate t9;
insert into t9(name, sex) values("Alex", "male"),("Coco", "female");
select * from t9;
執行結果爲:
mysql> create table t9(
-> id int primary key auto_increment, # 定義自增長字段
-> name varchar(20),
-> sex enum("male", "female"));
Query OK, 0 rows affected (1.60 sec)
mysql> desc t9;
+-------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| sex | enum('male','female') | YES | | NULL | |
+-------+-----------------------+------+-----+---------+----------------+
3 rows in set (0.05 sec)
mysql> insert into t9(name) values("Alex"),("Coco");
Query OK, 2 rows affected (0.31 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from t9; # 不指定id,則自動增長
+----+------+------+
| id | name | sex |
+----+------+------+
| 1 | Alex | NULL |
| 2 | Coco | NULL |
+----+------+------+
2 rows in set (0.00 sec)
mysql> insert into t9 values(5, "BeiBei", "female"); # 也可指指定id
Query OK, 1 row affected (0.23 sec)
mysql> select * from t9;
+----+--------+--------+
| id | name | sex |
+----+--------+--------+
| 1 | Alex | NULL |
| 2 | Coco | NULL |
| 5 | BeiBei | female |
+----+--------+--------+
3 rows in set (0.00 sec)
mysql> delete from t9;
Query OK, 3 rows affected (0.52 sec)
mysql> select * from t9;
Empty set (0.00 sec)
mysql> insert into t9(name, sex) values("Alex", "male"),("Coco", "female");
Query OK, 2 rows affected (0.18 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from t9; # 對於自增的字段,在用delete刪除後,再插入值,該字段仍按照刪除前的位置繼續增長
+----+------+--------+
| id | name | sex |
+----+------+--------+
| 6 | Alex | male |
| 7 | Coco | female |
+----+------+--------+
2 rows in set (0.00 sec)
mysql> truncate t9; # 應該用truncate清空表,比起delete一條一條地刪除記錄,truncate是直接清空表,在刪除大表時用它
Query OK, 0 rows affected (0.87 sec)
mysql> insert into t9(name, sex) values("Alex", "male"),("Coco", "female");
Query OK, 2 rows affected (0.09 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from t9;
+----+------+--------+
| id | name | sex |
+----+------+--------+
| 1 | Alex | male |
| 2 | Coco | female |
+----+------+--------+
2 rows in set (0.00 sec)
創建完表後可以修改自增細分的初始值
create table t10(
id int primary key auto_increment,
name varchar(20),
sex enum('male','female') default 'male');
alter table t10 auto_increment = 5; # 修改步長
show create table t10;
insert into t10(name) values("Alex");
select * from t10;
show create table t10;
執行結果爲:
mysql> create table t10(
-> id int primary key auto_increment,
-> name varchar(20),
-> sex enum('male','female') default 'male');
Query OK, 0 rows affected (0.72 sec)
mysql> alter table t10 auto_increment = 5;
Query OK, 0 rows affected (0.33 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table t10;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t10 | CREATE TABLE `t10` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`sex` enum('male','female') DEFAULT 'male',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> insert into t10(name) values("Alex");
Query OK, 1 row affected (0.24 sec)
mysql> select * from t10;
+----+------+------+
| id | name | sex |
+----+------+------+
| 5 | Alex | male |
+----+------+------+
1 row in set (0.00 sec)
mysql> show create table t10;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| t10 | CREATE TABLE `t10` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`sex` enum('male','female') DEFAULT 'male',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
查看MySQL的步長:
show session variables like "auto_inc%";
執行結果爲:
mysql> show session variables like "auto_inc%";
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| auto_increment_increment | 1 | # auto_increment_increment 表示步長
| auto_increment_offset | 1 | # auto_increment_offset 表示其實偏移量
+--------------------------+-------+
2 rows in set, 1 warning (0.15 sec)
可以通過下列命令設置步長:
set session auth_increment_increment=2 #修改會話級別的步長
set global auth_increment_increment=2 #修改全局級別的步長(所有會話都生效)
設置全局的起始偏移量和步長需要重新啓動MySQL。
如果auto_increment_offset的值大於auto_increment_increment的值,則auto_increment_offset的值會被忽略。