Linux MySQL --- 主键与外键

主键(PRIMARY KEY)

# 主键又叫主键约束,是MySQL中使用最为频繁的约束。一般为了便于DBMS更快的查找到表中的记录,都会在表中设置一个主键。

# 主键分为单字段主键和多字段联合主键

* 使用主键应该注意一下几点:

* 每个表只能定义一个主键

* 主键值必须唯一标识表中的每一行,且不能为NULL,即表中不可能存在有相同主键值的两行数据。这是唯一性原则。

* 一个字段名只能在联合主键字段表中出现一次

* 联合主键不能包含不必要的多余字段。当把联合主键的某一字段删除后,如果剩下的字段构成的主键仍然满足唯一性原则,那么这个联合主键是不正确的。这是最小化原则。

在创建表时设置主键约束

在创建数据表时设置主键约束,既可以为表中的一个字段设置主键,也可以为表中多个字段设置联合主键,但是不论使用哪种方法,在一个表中主键只能有一个。

1.设置单字段主键

# 在CREATE TABLE语句中,通过PRIMARY KEY关键字来指定主键。

在定义字段的同时指定主键

语法格式:<字段名> <数据类型> PRIMARY KEY [默认值]

MySQL [mysql_chuid]> create table students_5(id int(5) PRIMARY KEY,name char(10),sex char(5),weight int(3),height int(3));

Query OK, 0 rows affected (0.34 sec)

MySQL [mysql_chuid]> DESC students_5;   # 查看数据表的结构

+--------+----------+------+-----+---------+-------+

| Field  | Type     | Null | Key | Default | Extra |

+--------+----------+------+-----+---------+-------+

| id     | int(5)   | NO   | PRI | NULL    |       |

| name   | char(10) | YES  |     | NULL    |       |

| sex    | char(5)  | YES  |     | NULL    |       |

| weight | int(3)   | YES  |     | NULL    |       |

| height | int(3)   | YES  |     | NULL    |       |

+--------+----------+------+-----+---------+-------+

5 rows in set (0.03 sec)

或者是在定义完所有字段之后指定主键

语法格式:CREATE TABLE (字段1(数据类型)字段2(数据类型2)…,PRIMARY KEY [字段名]);

MySQL [mysql_chuid]> create table students_3(id int(5),name char(10),sex char(5),weight int(3),height int(3),PRIMARY KEY(id));

Query OK, 0 rows affected (0.09 sec)

MySQL [mysql_chuid]> desc students_3;   # 查看数据表的结构

+--------+----------+------+-----+---------+-------+

| Field  | Type     | Null | Key | Default | Extra |

+--------+----------+------+-----+---------+-------+

| id     | int(5)   | NO   | PRI | 0       |       |

| name   | char(10) | YES  |     | NULL    |       |

| sex    | char(5)  | YES  |     | NULL    |       |

| weight | int(3)   | YES  |     | NULL    |       |

| height | int(3)   | YES  |     | NULL    |       |

+--------+----------+------+-----+---------+-------+

5 rows in set (0.09 sec)

2.在创建表时设置联合主键

# 定义:联合主键指的是这个主键是由一张表中多个字段组成的

* 案例:设置学生选课数据表时,使用学生编号做主键还是用课程编号做主键呢?

* 如果用学生编号做主键,那么一个学生就只能选择一门课程。如果用课程编号做主键,那么一门课程只能有一个学生来选。显然这两种情况都不符合实际情况。

* 设计学生选课表,要限定的是一个学生只能选择同一课程一次。因此,学生编号和课程编号可以放在一起共同作为主键,这也就是联合主键了。

主键由多个字段联合组成(当主键由多个字段组成时,不能直接在字段后面声明主键约束。)

语法格式:PRIMARY KEY [字段1,字段2,…,字段n]

MySQL [mysql_chuid]> create table students_6(id int(5),name char(10),sex char(5),PRIMARY KEY(id,name));

Query OK, 0 rows affected (0.20 sec)

MySQL [mysql_chuid]> desc students_6;   # 查看数据表的结构

+-------+----------+------+-----+---------+-------+

| Field | Type     | Null | Key | Default | Extra |

+-------+----------+------+-----+---------+-------+

| id    | int(5)   | NO   | PRI | 0       |       |

| name  | char(10) | NO   | PRI |         |       |

| sex   | char(5)  | YES  |     | NULL    |       |

+-------+----------+------+-----+---------+-------+

3 rows in set (0.00 sec)

在修改表时添加主键约束

# 主键约束不仅可以在创建表的同时创建,也可以在修改表时添加。但是需要注意的是:设置成主键约束的字段中不允许有空值。

通常情况下,在修改表时要设置表中某个字段的主键约束时,要确保设置成主键约束的字段中值不能够有重复的,并且要保证是非空的,否则无法设置主键约束。

在修改数据表时添加主键约束

语法格式:ALTER TABLE <数据表名> ADD PRIMARY KEY(<字段名>);

MySQL [mysql_chuid]> create table students_7(id int(5),name char(10),sex char(5));

Query OK, 0 rows affected (0.11 sec)

MySQL [mysql_chuid]> desc students_7;

+-------+----------+------+-----+---------+-------+

| Field | Type     | Null | Key | Default | Extra |

+-------+----------+------+-----+---------+-------+

| id    | int(5)   | YES  |     | NULL    |       |

| name  | char(10) | YES  |     | NULL    |       |

| sex   | char(5)  | YES  |     | NULL    |       |

+-------+----------+------+-----+---------+-------+

3 rows in set (0.03 sec)

MySQL [mysql_chuid]> ALTER TABLE students_7 ADD PRIMARY key(id);

Query OK, 0 rows affected (0.17 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> desc students_7;

+-------+----------+------+-----+---------+-------+

| Field | Type     | Null | Key | Default | Extra |

+-------+----------+------+-----+---------+-------+

| id    | int(5)   | NO   | PRI | 0       |       |

| name  | char(10) | YES  |     | NULL    |       |

| sex   | char(5)  | YES  |     | NULL    |       |

+-------+----------+------+-----+---------+-------+

3 rows in set (0.00 sec)

删除主键约束

# 当一个表中不需要主键约束时,就需要从表中将其删除。删除主键约束的方法要比创建主键约束容易的多。

# 由于主键约束在一个表中只能有一个,因此不需要指定主键名就可以删除一个表中的主键约束。

删除主键约束的语法格式:ALTER TABLE <数据表名> DROP PRIMARY KEY;

MySQL [mysql_chuid]> ALTER TABLE students_7 DROP PRIMARY KEY;   # 删除主键约束

Query OK, 0 rows affected (0.31 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> DESC students_7;

+-------+----------+------+-----+---------+-------+

| Field | Type     | Null | Key | Default | Extra |

+-------+----------+------+-----+---------+-------+

| id    | int(5)   | NO   |     | 0       |       |

| name  | char(10) | YES  |     | NULL    |       |

| sex   | char(5)  | YES  |     | NULL    |       |

+-------+----------+------+-----+---------+-------+

3 rows in set (0.00 sec)

主键自增长

# 在MySQL中,当主键定义为自增长后,这个主键的值就不再需要用户输入了,而由数据库系统根据定义自动赋值。每增加一条记录,主键就会自动以相同的步长进行增长。

主键自增长语法格式:字段名 数据类型 AUTO_INCREMENT

* 默认情况下,AUTO_INCREMENT的初始值是1,每新增一条记录,字段值自动加1

* 一个表中只能有一个字段使用AUTO_INCREMENT约束,且该字段必须有唯一索引,以避免序号重复(即为主键或主键的一部分)

* AUTO_INCREMENT约束的字段必须具备NOT NULL属性

* AUTO_INCREMENT约束的字段只能是整数类型(TINYINT、SMALLINT、INT、BIGINT等)

* AUTO_INCREMENT约束字段的最大值受该字段的数据类型约束,如果达到上限,AUTO_INCREMENT就会失效

MySQL [mysql_chuid]> show tables;

+-----------------------+

| Tables_in_mysql_chuid |

+-----------------------+

| students              |

| students_1            |

| students_2            |

+-----------------------+

3 rows in set (0.04 sec)

MySQL [mysql_chuid]> create table students_3 (id int(5) PRIMARY KEY AUTO_INCREMENT,name char(25) NOT NULL,sex int(5));

Query OK, 0 rows affected (0.28 sec)

MySQL [mysql_chuid]> insert into students_3 (name,sex) values ('chuid',26);

Query OK, 1 row affected (0.08 sec)

MySQL [mysql_chuid]> select * from students_3;

+----+-------+------+

| id | name  | sex  |

+----+-------+------+

|  1 | chuid |   26 |

+----+-------+------+

1 row in set (0.00 sec)

指定自增长字段初始值

* 如果第一条记录设置了该字段的初始值,那么新增加的记录就从这个初始值开始自增。

MySQL [mysql_chuid]> create table students_6 (id int(5) PRIMARY KEY AUTO_INCREMENT,name char(25) NOT NULL,sex int(5)) AUTO_INCREMENT = 50 ;

Query OK, 0 rows affected (0.13 sec)

MySQL [mysql_chuid]> insert into students_6 (name,sex) values ('chuid',27);

Query OK, 1 row affected (0.04 sec)

MySQL [mysql_chuid]> desc students_6;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(5)   | NO   | PRI | NULL    | auto_increment |

| name  | char(25) | NO   |     | NULL    |                |

| sex   | int(5)   | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

3 rows in set (0.02 sec)

MySQL [mysql_chuid]> select * from students_6;

+----+-------+------+

| id | name  | sex  |

+----+-------+------+

| 51 | chuid |   27 |

+----+-------+------+

1 row in set (0.00 sec)

MySQL [mysql_chuid]> show table status like 'students_6'\G;    # 在MySQL中查询表的详细信息

*************************** 1. row ***************************

           Name: students_6

         Engine: InnoDB

        Version: 10

     Row_format: Compact

           Rows: 1

 Avg_row_length: 16384

    Data_length: 16384

Max_data_length: 0

   Index_length: 0

      Data_free: 0

 Auto_increment: 53

    Create_time: 2021-02-27 10:04:30

    Update_time: NULL

     Check_time: NULL

      Collation: latin1_swedish_ci

       Checksum: NULL

 Create_options:

        Comment:

1 row in set (0.00 sec)

自增字段值不连续

* 通过一个实例分析自增字段的值为什么不连续

* 创建表students_5,其中ID是自增主键字段,name是唯一性索引,语句如下:

MySQL [mysql_chuid]> create table students_5(id int PRIMARY KEY AUTO_INCREMENT,name char(20) UNIQUE KEY,age int DEFAULT NULL);

Query OK, 0 rows affected (0.09 sec)

MySQL [mysql_chuid]> INSERT INTO students_5 VALUES (1,'chd',27);

Query OK, 1 row affected (0.12 sec)

MySQL [mysql_chuid]> INSERT INTO students_5 VALUES (null,'chd',27);

ERROR 1062 (23000): Duplicate entry 'chd' for key 'name'

* 由于表中已经存在name=chd的记录,所以报Duplicate key error(唯一性冲突)。

* 在这之后,再次插入新的数据时,自增ID就是3,这样就出现了自增字段值不连续的情况。

 

外键约束(FOREIGN KEY)

# 外键约束时表的一个特殊字段,经常与主键约束一起使用。对于两个具有关联关系的表而言,相关联字段中主键所在的表就是主表(父表),外键所在的表就是从表(子表)。

# 创建外键约束,保证数据的完整性和一致性

* 主键表和外键表的理解:

* 1.以公共关键字做主键的表为主键表(父表、主表)

* 2.以公共关键字做外键的表为外键表(从表、外表)

与外键关联的主表的字段必须设置为主键,要求从表不能是临时表,主从表的字段具备相同的数据类型。字符长度和约束。

主表删除某条记录时,从表中与之对于的记录也必须有相应的改变。一个表可以有一个或多个外键,外键可以为空值,若不为空值,则每一个外键的值必须等于主表中主键的某个值。

* 定义外键时,需要遵守下列规则:

* 主表必须已经存在于数据库中,或是当前正在创建的表。如果是后一种情况,则主表与从表是同一个表,这样的表成为自参照表,这种结构称为自参照完整性。

* 必须为主表定义主键。

* 主键不能包含空值,但允许在外键中出现空值。也就是说只要外键的每个非空值出现在指定的主键中,这个外键的内容就是正确的。

* 在主表的表名后面指定列名或列名的组合。这个列或列的组合必须是主表的主键或候选键。

* 外键中列的数目必须和主表的主键中列的数目相同。

* 外键中列的数据类型必须和主表主键中对应的数据类型相同。

创建主表 students01:CREATE table students01 (hobid int(5),hobname varchar(50));

MySQL [mysql_chuid]> create table students01 (hobid int(5),hobname varchar(50));

Query OK, 0 rows affected (0.15 sec)

创建从表 students02: CREATE table students02 (id int(5) primary key auto_increment,name varchar(10) , age int(5) , hobid int(5));

MySQL [mysql_chuid]> create table students02 (id int(5) primary key auto_increment,name varchar(10),age int(5),hobid int(5));

Query OK, 0 rows affected (0.08 sec)

# 为主表students01添加一个主键约束。主键名建议以“PK_”开头

MySQL [mysql_chuid]> alter table students01 add constraint PK_hobid primary key(hobid);

Query OK, 0 rows affected (0.43 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> desc students01;

+---------+-------------+------+-----+---------+-------+

| Field   | Type        | Null | Key | Default | Extra |

+---------+-------------+------+-----+---------+-------+

| hobid   | int(5)      | NO   | PRI | 0       |       |

| hobname | varchar(50) | YES  |     | NULL    |       |

+---------+-------------+------+-----+---------+-------+

2 rows in set (0.01 sec)

# 为从表students02添加外键,并将表students02的hobid字段和表students01的hobid字段建立外键关联,外键名建议以“FK_”开头。

# 修改students02增加约束,约束字段hobid

MySQL [mysql_chuid]> alter table students02 add constraint FK_hob foreign key (hobid) references students01 (hobid);

Query OK, 0 rows affected (0.13 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> desc students02;

+-------+-------------+------+-----+---------+----------------+

| Field | Type        | Null | Key | Default | Extra          |

+-------+-------------+------+-----+---------+----------------+

| id    | int(5)      | NO   | PRI | NULL    | auto_increment |

| name  | varchar(10) | YES  |     | NULL    |                |

| age   | int(5)      | YES  |     | NULL    |                |

| hobid | int(5)      | YES  | MUL | NULL    |                |

+-------+-------------+------+-----+---------+----------------+

4 rows in set (0.02 sec)

# 插入新的数据记录时要先主表再从表

MySQL [mysql_chuid]> insert into students01 values (1,'chen');   # 先增加主键表的内容

Query OK, 1 row affected (0.01 sec)

MySQL [mysql_chuid]> insert into students02 values (1,'chd','25',1);    # 主键表增加内容后才可增加外键表的内容

Query OK, 1 row affected (0.00 sec)

MySQL [mysql_chuid]> select * from students01;

+-------+---------+

| hobid | hobname |

+-------+---------+

|     1 | chen    |

+-------+---------+

1 row in set (0.00 sec)

MySQL [mysql_chuid]> select * from students02;

+----+------+------+-------+

| id | name | age  | hobid |

+----+------+------+-------+

|  1 | chd  |   25 |     1 |

+----+------+------+-------+

1 row in set (0.02 sec)

在创建表时设置外键约束

在CREATE TABLE语句中,通过FOREIGN KEY关键字来指定外键,语法格式:

[CONSTRAINT <外键名>] FOREIGN KEY 字段名 [,字段名2,…]

REFERENCES <主表名> 主键列1 [,主键列2,…]

例:为了说明表与表之间的外键关系,在mysql_chuid数据库中创建一个班级表students_3

字段名称

数据类型

备注

id

int(5)

班级编号

name

varchar(10)

班级名称

grades

varchar(10)

班级成绩

MySQL [mysql_chuid]> create table students_3(id int(5) PRIMARY KEY,name varchar(10) NOT NULL,grades varchar(10));

Query OK, 0 rows affected (0.11 sec)

# 创建数据表class_1,并在表class_1上创建外键约束,让她的键claID作为外键关联到表students_3的主键id

MySQL [mysql_chuid]> create table class_1(id int(5) PRIMARY KEY,name varchar(10),claID int(10),grades float,CONSTRAINT FK_cla_stu3 FOREIGN KEY(claID) REFERENCES students_3(id));

Query OK, 0 rows affected (0.20 sec)

# SQL语句执行成功后,在表class_1上添加了名称为FK_cla_stu3的外键约束,外键名称为claID,其依赖于表students_3的主键id

MySQL [mysql_chuid]> desc class_1;

+--------+-------------+------+-----+---------+-------+

| Field  | Type        | Null | Key | Default | Extra |

+--------+-------------+------+-----+---------+-------+

| id     | int(5)      | NO   | PRI | NULL    |       |

| name   | varchar(10) | YES  |     | NULL    |       |

| claID  | int(10)     | YES  | MUL | NULL    |       |

| grades | float       | YES  |     | NULL    |       |

+--------+-------------+------+-----+---------+-------+

4 rows in set (0.00 sec)

MySQL [mysql_chuid]> ALTER table class_1 DROP FOREIGN KEY FK_cla_stu3;  # 删除外键约束

Query OK, 0 rows affected (0.02 sec)

Records: 0  Duplicates: 0  Warnings: 0

* 从表的外键关联的必须是主表的主键,且主键和外键的数据类型必须一致。例:两者都是int类型或都是char类型。如果不满足这样的要求,在创建从表时就会报错!

在修改表时添加外键约束

外键约束也可以在修改表时添加,但是添加外键约束的前提是:从表中外键列中的数据必须与主表中主键列中的数据一致或是没有数据。

在修改数据表时添加外键约束的语法格式:

ALTER TABLE <数据表名> ADD CONSTRAINT <外键名>

FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);

MySQL [mysql_chuid]> create table students_2(id int(5) PRIMARY KEY,name char(10),claID int(5),grades varchar(10));  # 创建表students_2

Query OK, 0 rows affected (0.08 sec)

MySQL [mysql_chuid]> create table class_2(id int(5),name char(10),claID int(5),grades float);   # 创建表class_2

Query OK, 0 rows affected (0.03 sec)

# 修改数据表class_2,将字段claID设置为外键,与数据表students_2的主键id进行关联

MySQL [mysql_chuid]> ALTER table class_2 ADD CONSTRAINT FK_cla_stu2 FOREIGN KEY(claID) REFERENCES students_2(id);

Query OK, 0 rows affected (0.11 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> show create table class_2\G    # 查看表创建的类型

*************************** 1. row ***************************

       Table: class_2

Create Table: CREATE TABLE `class_2` (

  `id` int(5) DEFAULT NULL,

  `name` char(10) DEFAULT NULL,

  `claID` int(5) DEFAULT NULL,

  `grades` float DEFAULT NULL,

  KEY `FK_cla_stu2` (`claID`),

  CONSTRAINT `FK_cla_stu2` FOREIGN KEY (`claID`) REFERENCES `students_2` (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.19 sec)

* 在为已经创建好的数据表添加外键约束时,要确保添加外键的列的值全部来源于主键列,并且外键列不能为空。

删除外键约束

当一个表中不需要外键约束时,就需要从表中将其删除。外键一旦删除,就会解除主表和从表键的关联关系。

删除外键约束的语法格式:ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>;

MySQL [mysql_chuid]> ALTER table class_2 DROP FOREIGN KEY FK_cla_stu2;

Query OK, 0 rows affected (0.07 sec)

Records: 0  Duplicates: 0  Warnings: 0

# 可以看到表class_2中已经不存在FOREIGN KEY,原有的名称为FK_cla_stu2的外键约束删除成功

MySQL [mysql_chuid]> show create table class_2\G

*************************** 1. row ***************************

       Table: class_2

Create Table: CREATE TABLE `class_2` (

  `id` int(5) DEFAULT NULL,

  `name` char(10) DEFAULT NULL,

  `claID` int(5) DEFAULT NULL,

  `grades` float DEFAULT NULL,

  KEY `FK_cla_stu2` (`claID`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.00 sec)

# 删除时,要先删除从表,再删除主表,否则会报错;因为主表可能关联多个从表,外键约束保证数据的完整性和一致性。

MySQL [mysql_chuid]> drop table students02;

Query OK, 0 rows affected (0.01 sec)

MySQL [mysql_chuid]> drop table students01;

Query OK, 0 rows affected (0.01 sec)

# 如果要删除外键约束字段,先删除外键约束,再删除外键名

MySQL [mysql_chuid]> show create table students02;

MySQL [mysql_chuid]> alter table students02 drop foreign key FK_hobid;

MySQL [mysql_chuid]> alter table students02 drop key FK_hobid;

MySQL [mysql_chuid]> desc students02;

在创建表时设置唯一性约束(UNIQUE KEY)

# 唯一性约束是指所有记录中字段的值不能重复出现。例如,为ID字段加上唯一性约束后,每条记录的ID值都是唯一的,不能出现重复的情况。

# 唯一性约束与主键约束相似的是他们都可以确保列的唯一性。不同的是,唯一性约束在一个表中可以有多个,并且设置唯一性约束的列允许有空值,但是只能有一个空值。而主键约束在一个表中只能有一个,且不允许有空值。比如用户信息表中,为了避免表中用户名重名,可以把用户名设置为唯一性约束。

# 唯一性约束可以在创建表时直接设置,通常设置在除了主键以外的其它列上。

语法格式:<字段名> <数据类型> UNIQUE

MySQL [mysql_chuid]> create table students_7(id int(5) PRIMARY KEY,name VARCHAR(10) UNIQUE, sex int(5),age int(5));

Query OK, 0 rows affected (0.21 sec)

MySQL [mysql_chuid]> desc students_7;

+-------+-------------+------+-----+---------+-------+

| Field | Type        | Null | Key | Default | Extra |

+-------+-------------+------+-----+---------+-------+

| id    | int(5)      | NO   | PRI | NULL    |       |

| name  | varchar(10) | YES  | UNI | NULL    |       |

| sex   | int(5)      | YES  |     | NULL    |       |

| age   | int(5)      | YES  |     | NULL    |       |

+-------+-------------+------+-----+---------+-------+

4 rows in set (0.04 sec)

在修改表时添加唯一性约束

语法格式:ALTER TABLE <数据表名> ADD CONSTRAINT <唯一约束名> UNIQUE(<列名>);

MySQL [mysql_chuid]> ALTER TABLE students_7 ADD CONSTRAINT unique_name UNIQUE(name);  # 指定name的名称唯一

Query OK, 0 rows affected, 1 warning (0.40 sec)

Records: 0  Duplicates: 0  Warnings: 1

MySQL [mysql_chuid]> desc students_7;

+-------+-------------+------+-----+---------+-------+

| Field | Type        | Null | Key | Default | Extra |

+-------+-------------+------+-----+---------+-------+

| id    | int(5)      | NO   | PRI | NULL    |       |

| name  | varchar(10) | YES  | UNI | NULL    |       |

| sex   | int(5)      | YES  |     | NULL    |       |

| age   | int(5)      | YES  |     | NULL    |       |

+-------+-------------+------+-----+---------+-------+

4 rows in set (0.01 sec)

删除唯一性约束

删除唯一性约束的语法格式:ALTER TABLE <表名> DROP INDEX <唯一约束名>;

删除数据表students_7中的唯一性约束unique_name

MySQL [mysql_chuid]> ALTER TABLE students_7 DROP INDEX unique_name;

Query OK, 0 rows affected (0.16 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> desc students_7;

+-------+-------------+------+-----+---------+-------+

| Field | Type        | Null | Key | Default | Extra |

+-------+-------------+------+-----+---------+-------+

| id    | int(5)      | NO   | PRI | NULL    |       |

| name  | varchar(10) | YES  | UNI | NULL    |       |

| sex   | int(5)      | YES  |     | NULL    |       |

| age   | int(5)      | YES  |     | NULL    |       |

+-------+-------------+------+-----+---------+-------+

4 rows in set (0.01 sec)

检查约束(CHECK)

检查约束是用来检查数据表中字段值有效性的一种手段,可以通过CREATE TABLE或ALTER TABLE语句实现。设置检查约束时要根据实际情况进行设置,这样才能够减少无效数据的输入。

选取设置检查约束的字段

检查约束的语法格式:CHECK <表达式>   # <表达式>指的是SQL表达式,用于指定需要检查的限定条件

若将CHECK约束子句置于表中某个列的定义之后,则这种约束也称为基于列的CHECK约束。

在更新表数据的时候,系统会检查更新后的数据行是否满足CHECK约束中的限定条件。MySQL可以使用简单的表达式来实现CHECK约束,也允许使用复杂的表达式作为限定条件,例如在限定条件中加入子查询。

若将CHECK约束子句置于所有列的定义以及主键约束和外键定义之后,则这种约束也称为基于表的CHECK约束,该约束可以同时对表中多个列设置限定条件。

在创建表时设置检查约束

如果系统的表结构已经设计完成,那么在创建表时就可以为字段设置检查约束了。

创建表时设置检查约束的语法格式:CHECK(<检查约束>)

MySQL [mysql_chuid]> CREATE table class_3(id int(5) PRIMARY KEY,name varchar(10),claID int(5),grades float,CHECK(grades>0 AND grades<100),FOREIGN KEY(claID) REFERENCES students_3(id));

Query OK, 0 rows affected (0.09 sec)

MySQL [mysql_chuid]> show create table class_3\G    # 查看表创建的类型

在修改表时添加检查约束

如果一个表创建完成,可以通过修改表的方式为表添加检查约束。

修改表是设置检查约束的语法格式:ALTER TABLE <表名> ADD CONSTRAINT <检查约束名> CHECK(<检查约束>)

MySQL [mysql_chuid]> alter table class_2 ADD CONSTRAINT check_id CHECK(id>0);  # 修改表class_2,要求id字段值大于0

Query OK, 0 rows affected (0.01 sec)

Records: 0  Duplicates: 0  Warnings: 0

删除检查约束

修改表时删除检查约束的语法格式:ALTER TABLE <数据表名> DROP CONSTRAINT <检查约束名>;

# 删除class_2表中的check_id检查约束

MySQL [mysql_chuid]> alter table class_1 DROP CONSTRAINT check_id;

默认值约束(DEFAULT)

默认值约束是用来指定某列的默认值。在表中插入一条新记录时,如果没有为某个字段赋值,系统就会自动为这个字段插入默认值。

# 例:学生统计表中,学生来自湖北的比较多,那么籍贯就可以默认为“湖北”,系统就会自动为这个字段赋值为“湖北”

* 默认值约束通常用在已经设置了非空约束的列,这样能够防止数据表在录入数据时出现错误。

在创建表时设置默认值约束

创建表时设置默认值约束,语法格式:<字段名> <数据类型> DEFAULT <默认值>;

# 创建数据表class_2 指定籍贯地址默认为Hubei

MySQL [mysql_chuid]> create table class_2(id int(5) PRIMARY KEY,name varchar(10),hometown varchar(10) DEFAULT 'Hubei');

Query OK, 0 rows affected (0.09 sec)

# SQL语句执行成功后,表class_2上的字段hometown的默认值为Hubei,新插入的学生记录如果没有指定籍贯,则默认都为Hubei

MySQL [mysql_chuid]> desc class_2;

+----------+-------------+------+-----+---------+-------+

| Field    | Type        | Null | Key | Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id       | int(5)      | NO   | PRI | NULL    |       |

| name     | varchar(10) | YES  |     | NULL    |       |

| hometown | varchar(10) | YES  |     | Hubei   |       |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.07 sec)

* 在创建表时为列添加默认值,可以一次为多个列添加默认值,需要注意不同列的数据类型。

在修改表时添加默认值约束

修改表时添加默认值约束的语法格式:ALTER TABLE <数据表名> CHANGE COLUMN <字段名> <数据类型> DEFAULT <默认值>;

# 修改表class_2,将籍贯地址的默认值修改为Wuhan

MySQL [mysql_chuid]> ALTER table class_2 CHANGE COLUMN hometown hometown varchar(10) DEFAULT 'Wuhan';

Query OK, 0 rows affected (0.01 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> desc class_2;

+----------+-------------+------+-----+---------+-------+

| Field    | Type        | Null | Key | Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id       | int(5)      | NO   | PRI | NULL    |       |

| name     | varchar(10) | YES  |     | NULL    |       |

| hometown | varchar(10) | YES  |     | Wuhan   |       |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.00 sec)

删除默认值约束

当一个表中的列不需要设置默认值时,就需要从表中将其删除。

修改表时删除默认值约束的语法格式:ALTER TABLE <数据表名> CHANGE COLUMN <字段名> <字段名> <数据类型> DEFAULT NULL;

MySQL [mysql_chuid]> alter table class_2 CHANGE COLUMN hometown hometown varchar(10) DEFAULT NULL;

Query OK, 0 rows affected (0.01 sec)

Records: 0  Duplicates: 0  Warnings: 0

# 修改数据表class_2,将籍贯地址的默认值约束删除:

MySQL [mysql_chuid]> desc class_2;

+----------+-------------+------+-----+---------+-------+

| Field    | Type        | Null | Key | Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id       | int(5)      | NO   | PRI | NULL    |       |

| name     | varchar(10) | YES  |     | NULL    |       |

| hometown | varchar(10) | YES  |     | NULL    |       |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.00 sec)

非空约束(NOT NULL)

非空约束指的是字段的值不能为空。对于使用了非空约束的字段,如果用户在添加数据时没有指定值,数据库系统就会报错。

可以通过CREATE TABLE或ALTER TABLE语句实现。在表中某个列的定义后加上关键字NOT NULL作为限定词,来约束该列的取值不能为空。

例:在用户信息表中,如果不添加用户名,那么这条用户信息就是无效的,这时就可以为用户名字段设置非空约束。

在创建表时设置非空约束

创建表时设置非空约束的语法格式:<字段名> <数据类型> NOT NULL;

MySQL [mysql_chuid]> create table class_3(id int(5) PRIMARY KEY,name varchar(10) NOT NULL,hometown varchar(10));

Query OK, 0 rows affected (0.09 sec)

MySQL [mysql_chuid]> desc class_3;

+----------+-------------+------+-----+---------+-------+

| Field    | Type        | Null | Key | Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id       | int(5)      | NO   | PRI | NULL    |       |

| name     | varchar(10) | NO   |     | NULL    |       |

| hometown | varchar(10) | YES  |     | NULL    |       |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.01 sec)

在修改表时添加非空约束

如果在创建表时忘记了为字段设置为空约束,也可以通过修改表进行非空约束的添加。

修改表时设置非空约束的语法格式:ALTER TABLE <数据表名> CHANGE COLUMN <字段名> <字段名> <数据类型> NOT NULL;

# 修改数据表class_2,指定籍贯地址不能为空:

MySQL [mysql_chuid]> ALTER table class_2 CHANGE COLUMN hometown hometown varchar(10) NOT NULL;

Query OK, 0 rows affected (0.36 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> desc class_2;

+----------+-------------+------+-----+---------+-------+

| Field    | Type        | Null | Key | Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id       | int(5)      | NO   | PRI | NULL    |       |

| name     | varchar(10) | YES  |     | NULL    |       |

| hometown | varchar(10) | NO   |     | NULL    |       |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.01 sec)

删除非空约束

修改表时删除非空约束的语法格式:ALTER TABLE <数据表名> CHANGE COLUMN <字段名> <字段名> <数据类型> NULL;

# 修改数据表class_3,将籍贯地址的非空约束删除:

MySQL [mysql_chuid]> ALTER table class_2 CHANGE COLUMN hometown hometown varchar(10) NULL;

Query OK, 0 rows affected (0.08 sec)

Records: 0  Duplicates: 0  Warnings: 0

MySQL [mysql_chuid]> desc class_2;

+----------+-------------+------+-----+---------+-------+

| Field    | Type        | Null | Key | Default | Extra |

+----------+-------------+------+-----+---------+-------+

| id       | int(5)      | NO   | PRI | NULL    |       |

| name     | varchar(10) | YES  |     | NULL    |       |

| hometown | varchar(10) | YES  |     | NULL    |       |

+----------+-------------+------+-----+---------+-------+

3 rows in set (0.00 sec)

查看表中的约束

查看数据表中的约束语法格式:SHOW CREATE TABLE <数据表名>;

# 创建数据表class_5并制定id为主键约束,name为唯一性约束,claID为非空约束和外键约束

MySQL [mysql_chuid]> CREATE table class_5(id int(5) PRIMARY KEY,name varchar(10) UNIQUE,claID int(5) NOT NULL,grades float DEFAULT 0,CHECK(grades>0),FOREIGN KEY(claID) REFERENCES students_5(id));

Query OK, 0 rows affected (0.11 sec)

MySQL [mysql_chuid]> desc students_5;

+-------+----------+------+-----+---------+----------------+

| Field | Type     | Null | Key | Default | Extra          |

+-------+----------+------+-----+---------+----------------+

| id    | int(11)  | NO   | PRI | NULL    | auto_increment |

| name  | char(20) | YES  | UNI | NULL    |                |

| age   | int(11)  | YES  |     | NULL    |                |

+-------+----------+------+-----+---------+----------------+

3 rows in set (0.01 sec)

MySQL [mysql_chuid]> show create table class_5 \G   # 查看表中的约束

*************************** 1. row ***************************

       Table: class_5

Create Table: CREATE TABLE `class_5` (

  `id` int(5) NOT NULL,

  `name` varchar(10) DEFAULT NULL,

  `claID` int(5) NOT NULL,

  `grades` float DEFAULT '0',

  PRIMARY KEY (`id`),

  UNIQUE KEY `name` (`name`),

  KEY `claID` (`claID`),

  CONSTRAINT `class_5_ibfk_1` FOREIGN KEY (`claID`) REFERENCES `students_5` (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=latin1

1 row in set (0.01 sec)

MySQL中6种常见的约束

主键约束(primary key)

外键约束(foreign key)

非空约束(not null)

唯一性约束(unique [key | index])

默认值约束(default)

自增约束(auto_increment)

猜你喜欢

转载自blog.csdn.net/C_huid/article/details/115265926
今日推荐