表的约束
表中一定要有各种约束,通过约束,让我们未来插入数据库表中的数据是符合预期的。
有了约束插入的数据就有了条件,为了保证数据的可预期性。

1.空属性
- 两个值:null(默认的)和not null(不为空)
- 数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没法参与运算。
sql
create table if not exists myclass(
-> class_name varchar(20) not null,
-> class_room varchar(20) not null,
-> other varchar(20)
-> );
class_name和class_room不能为空,插入时需要有数据
2.默认值
sql
create table if not exists t1(
-> name varchar(20) not null,
-> age tinyint unsigned default 18,
-> gender char(1) default '男'
-> );
- 不插入时使用默认值
- 如果我们没有明确指定一列要插入,用的时default,如果建表中,对应列默认没有设置default值,无法直接插入。
- 写了就被NULL约束,不写就被default约束,default默认值是NULL
3. comment注释
没有实际含义,专门用来描述字段
4.zerofill(补零)
int(10)unsigned 加上zerofill不够的位数补0,没有zerofill就只显示有的位数
有符号int是int(11)有11位
5.主键
主键:primary key用来唯一的约束字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键,主键所在的列通常是整数类型。
一个主键可以被添加到一列,也可以添加到多列上:复合主键
sql
create table if not exists test_key(
-> id int unsigned primary key comment '这个是学生的学号',
-> name varchar(20) not null
-> );
插入的id具有唯一性,相同的id不能插入进来
sql
alter table 表名 drop primary key; #删掉主键
alter table 表名 add primary key(id); #添加主键
delete from test_key where name='孙权'; #删除
复合主键
sql
create table pick_course(
-> id int unsigned,
-> course_id int unsigned comment '课程编号',
-> score tinyint unsigned comment '这个学生课程考的分数',
-> primary key(id,course_id)
-> );
desc pick_course;
+-----------+---------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+-------+
| id | int(10) unsigned | NO | PRI | NULL | |
| course_id | int(10) unsigned | NO | PRI | NULL | |
| score | tinyint(3) unsigned | YES | | NULL | |
+-----------+---------------------+------+-----+---------+-------+
id和course_id合起来是一个主键
自增长auto_increment
sql
create table if not exists tt21(
-> id int unsigned primary key auto_increment,
-> name varchar(20) not null
-> );
- 自增长只能有一个
- 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
6.唯一键unique
唯一键可以为NULL,主键不能有两个重复的NULL
唯一键弥补了主键的不足:主键只能让一列或者多列不能重复
唯一键可以让多列保持唯一性。
sql
create table student (
-> id char(20) primary key,
-> name varchar(32) not null,
-> telphone char(20) unique key,
-> qq varchar(64) unique key
-> );
desc student;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| id | char(20) | NO | PRI | NULL | |
| name | varchar(32) | NO | | NULL | |
| telphone | char(20) | YES | UNI | NULL | |
| qq | varchar(64) | YES | UNI | NULL | |
+----------+-------------+------+-----+---------+-------+
一般而言,我们建议将主键设计成为和当前业务无关的字段,这样,当业务调整的时候,我们可以尽量不会对主键做过大的调整。
7.外键
外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或者unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或者为null。
语法
foreign key (字段名) references 主表(列)
初识"外键"
主表class
sql
create table if not exists class(
-> id int unsigned primary key auto_increment,
-> name varchar(20) not null
-> );
mysql> select * from class;
+----+---------------+
| id | name |
+----+---------------+
| 1 | 计科2601班 |
| 2 | 计科2602班 |
+----+---------------+
从表student
sql
create table if not exists student(
-> id int unsigned primary key auto_increment,
-> name varchar(20) not null,
-> telphone varchar(32) unique key,
-> class_id int unsigned,
-> foreign key(class_id) references class(id)
-> );
mysql> desc student;
+----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
| telphone | varchar(32) | YES | UNI | NULL | |
| class_id | int(10) unsigned | YES | MUL | NULL | |
+----------+------------------+------+-----+---------+----------------+
在 MySQL 中,外键要求数据类型、长度、有无符号、字符集(若是字符串)必须完全一致。int 和 int unsigned 被视为不同类型,因此约束失败。
如何为已建的表添加外键
在 MySQL 中,可以使用 ALTER TABLE 语句为已创建的表添加外键。
1. 基本语法
最常用的完整语法如下:
sql
ALTER TABLE 子表名
ADD CONSTRAINT 外键名
FOREIGN KEY (子表外键列名) REFERENCES 主表名(主表列名)
[ON DELETE 动作]
[ON UPDATE 动作];
2. 详细示例
假设我们有两张表:customers(客户表)是主表,orders(订单表)是子表。我们要让 orders 表中的 customer_id 字段引用 customers 表中的 id 字段。
sql
-- 1. 创建主表 customers
CREATE TABLE customers (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(100)
) ENGINE=InnoDB;
-- 2. 创建子表 orders (暂时没有外键)
CREATE TABLE orders (
id INT PRIMARY KEY AUTO_INCREMENT,
order_date DATE,
customer_id INT
) ENGINE=InnoDB;
-- 3. 为已存在的 orders 表添加外键
ALTER TABLE orders
ADD CONSTRAINT fk_orders_customers -- 指定一个有意义的外键名
FOREIGN KEY (customer_id) -- 子表中的外键列
REFERENCES customers(id); -- 主表及其被引用的列
添加成功后,orders 表的 customer_id 列的值必须存在于 customers 表的 id 列中。
3. 重要注意事项
在执行添加操作前,请确认以下几点,否则操作会失败:
- 存储引擎 :表和必须 使用
InnoDB存储引擎,MySQL 的其他引擎(如 MyISAM)不支持外键。 - 字段类型匹配 :外键字段与主表被引用的字段,其数据类型和长度必须完全一致。
- 主表有索引 :被引用的主表字段必须 有主键或唯一键(
UNIQUE)约束。 - 数据一致性 :子表外键列中已有的数据,必须在主表被引用列中存在,否则无法添加外键。
- 约束命名 :建议使用
CONSTRAINT 外键名来明确命名,方便后续管理。
4. 级联操作(ON DELETE / ON UPDATE)
你可以通过 ON DELETE 和 ON UPDATE 子句,定义当主表数据被删除或更新时,子表如何自动响应。
CASCADE:主表数据删除/更新时,子表相关数据也自动删除/更新。SET NULL:主表数据删除/更新时,子表的外键列自动设为NULL(该列需允许为空)。RESTRICT:如果子表有相关数据,则禁止删除/更新主表数据(默认行为)。
示例:当删除一个客户时,自动删除其所有订单。
sql
ALTER TABLE orders
ADD CONSTRAINT fk_orders_customers
FOREIGN KEY (customer_id) REFERENCES customers(id)
ON DELETE CASCADE;