非空约束
非空约束确保列不接受NULL值
- 创建表时表示非约束
create table 表名(
字段名 not null,
......
);
例:
create table users(
id int not null,
name varchar(20)
);
#报错,id没有默认值,不允许为空
insert into users(name) values("李四");
- 在已有字段添加非空约束
alter table 表名
modify column 字段名 字段类型 not null;
例:
alter table employees
modify column name varchar(100) not null;
# 其中的 column 写不写都可以
注意:不要混淆NULL值和空串,NULL值就是没有值,空串是’'(两个单引号,中间没有字段)
默认约束
default, 如果在插入行时没有给出值,通过default指定此时使用的默认值
create table 表名(
字段名 字段类型 default 默认值,
。。。
);
例:
create table users(
id int not null default 666,
name varchar(20)
);
#不报错 默认填充666
insert into users(name) values("李四");
select * from users;
# 修改已有字段
alter table users
MODIFY COLUMN status VARCHAR(10) DEFAULT 'active';
注意事项
- 不能为text类型或blob类型的字段设置默认值。(text 和 blob 类型:用于存放大文本或二进制数据。)
create table t1 (
content text default 'default text'
);
# 会报错,因为TEXT类型不能有默认值。
唯一约束
用于确保特定列或列组合的唯一性,被约束的列的值在整个表中是唯一的,唯一约束默认允许空值(null),因此多个空值不违反唯一约束
create table 表名(
字段名 字段类型 unique,
。。。
);
create table users (
id int primary key,
email varchar(100) unique,
username varchar(50),
phone varchar(20),
unique (username, phone)
/*
email:每个用户的邮箱唯一
(username, phone):用户的“用户名 + 电话号码”组合唯一(复合唯一)
*/
);
- 在已有的字段上进行添加唯一字段
alter table users add unique (email);
- 添加符合唯一索引
alter table users add unique index unique_username_phone (username, phone);
删除唯一索引:
alter table 表名
drop index 约束名;
alter table 表名
drop key 约束名;
唯一约束与主键的区别
特点 | 主键(PRIMARY KEY) | 唯一约束(UNIQUE) |
---|---|---|
唯一性 | 必须唯一,且非空(NOT NULL) | 唯一,可以为空,但此行为依赖数据库版本和设置 |
数量限制 | 每个表只能有一个主键 | 可以有多个唯一约束 |
主要用途 | 表的标识,唯一标记每行 | 保证其他列值的唯一性 |
用途解释:
- 表的标识,唯一标记每行
意思:特别是在有多个列组成的“复合唯一索引”或某个单列具有唯一约束时,是用来标识每一行数据的“唯一身份证”。
举例:
- 你有一个用户表,除了主键(比如id),还想确保每个邮箱(email)都不重复,这样每个邮箱可以作为用户的唯一身份标志。
- 再比如,“订单编号”字段,设置唯一,保证每个订单都可以唯一识别。
假设你有一个用户表,存放一些用户的信息:
id | 用户名 | 邮箱 | 手机号 |
---|---|---|---|
1 | 张三 | zhangsan@example.com | 13800138000 |
2 | 李四 | lisi@example.com | 13900139000 |
3 | 王五 | wangwu@example.com | 13700137000 |
- 用“主键(如id)作为“唯一标识”
id 是每个用户的唯一编号,保证每一行数据都能唯一识别,没有重复的 id。
这样,如果要找到“李四”的信息,只需要用 id=2,就能唯一找到。
- 用“邮箱”字段作为“唯一标识”
如果你规定“每个邮箱都必须唯一”,那么:
alter table users add unique (email);
目的:确保每条数据都可以唯一对应到一行,避免重复或混淆
简单理解:
“唯一标记每行”意味着:在表里,每一行有一个唯一的识别符(比如id),可以用来准确找到这条数据,不会搞混。
其他列(如邮箱)可以用来保证没有重复,是“内容的唯一性”要求。
- 保证其他列值的唯一性
意思:限制某些列((或列的组合))的值不能重复,用于确保数据的“唯一性”和“完整性”。
举例:
- 用户名不能重复:每个用户名都必须唯一;
- 电话号码组合必须唯一:不能出现两个用户同一个手机号;
- 这样可以避免重复数据,保证数据准确。
注意事项
- 用于保持数据的一致性和完整性。
- 字段值必须满足唯一性限制,插入重复值会出错。
- 在设计数据库时,应合理设置唯一约束,防止数据错误。
主键约束
唯一标识表中每行的这个列(或这组列)称为主键。主键用来表示一个特定的行。没有主键,更新或删除表中特定行很困难,因为没有安全的方法保证只涉及相关的行。
因此:
- 每一个表都应该定义主键
- 主键的值不应该修改
- 不使用可能会修改值的列作为主键(与业务无关,通常使用id作为主键)
特点:
- 唯一性:主键要求每一行数据的主键值都必须是唯一的,不允许有重复值。
- 非空性:主键要求主键列的值不能为空,即不能为NULL。
- 单一性:每个表只能有一个主键。主键可以由一个列或多个列组成,形成复合主键列级
作用:
- 快速查找、更新或删除某一行数据。
- 在表与表之间建立关联(外键关联)。
create table 表名(
字段名 字段类型 primary key,
....
);
创建表时直接定义主键
create table users (
id int primary key,
username varchar(50),
email varchar(100)
);
id字段就是表的主键,保证每个用户的ID都唯一,且不能为空。
定义多个字段组合为复合主键
create table enrollments (
student_id int,
course_id int,
enrollment_date date,
primary key (student_id, course_id)
);
修改表添加主键
alter table users add primary key (id);
删除主键
alter table 表名
drop primary key;
自动递增
auto_increment: 设置ayto_increment的列,当每增加一行时自动增量,每个表只允许一个auto_increment列
create table users(
id int primary key auto_increment,
name varchar(20) unique
);
insert into users(name) values("李四");
insert into users(name) values("张三");
insert into users(id,name) values("王五")
insert into users(name) values("赵六");
总结
特点 | 说明 |
---|---|
必须唯一 | 每行数据的主键值都不同 |
非空 | 不能为空 |
作用 | 标识和区分每一行,是数据关系和索引的基础 |
只能有一个主键 | 一个表只能有一个主键 |
外键约束
外键为表中的某一字段,该字段是另一表的主键值,外键用来在两个表的数据之间建立联结,一个表中可以有一个或多个外键。外键的作用是保持数据的一致性、完整性。
注意:
- 保证子表中的数据只能是父表中存在的值,外键字段可以为 null,外键为空的数据也叫孤儿数据
- 有了外键引用之后,表分为父表和子表
- 创建表时先创建父表,再创建子表
- 插入数据时,先插入父表数据,再插入子表数据
- 删除时先删除子表,再删除父表
- 子表外键类型要与父表外键类型一致
例:
假设有两个表:orders(订单)和customers(客户)
create table customers (
customer_id int primary key,
name varchar(50)
);
订单表加入外键:
create table orders (
order_id int primary key,
customer_id int,
order_date date,
foreign key (customer_id) references customers(customer_id)
);
外键的特点和限制
- 外键列必须是引用的主键或唯一索引。
- 子表的外键值必须在父表存在(除非允许空值)。
- 外键字段可以是单列或多列(复合外键)。
- 不能在包含相关数据的父表被删除或修改时,破坏数据完整性(除非定义了级联操作)。
- 数据一致性:比如,不能在订单中输入一个不存在的客户编号。
- 关系维护:可以建立“一对多”或“多对多”的关系。
定义外键时可以使用的动作
常用:
- cascade:删除/更新父行时,自动删除/更新子行
- set NULL:删除/更新父行后,子行外键设为NULL
- set default:设置为默认值(少用或不支持)
- restrict或no action:阻止删除/更新,若有关联数据
级联
- 级联删除(cascade delete):当父表中的某条记录被删除时,所有关联的子表记录也会自动被删除。
- 级联更新(cascade update):当父表中的某条记录的主键被修改时,关联的子表中的外键也会自动跟着更新。
例;
foreign key (customer_id) references customers(customer_id)
on delete cascade
on update cascade
- on delete cascade:
如果删除customers表中的某个customer_id,那么所有orders中对应这个customer_id的订单也会自动被删除。
- on update cascade:
如果修改customers表中某个customer_id的值(比如改ID),那么所有orders表中对应的外键也会自动同步更新为新的ID。
总结
操作 | 作用 | 例子 |
---|---|---|
on delete cascade |
删除父表记录时,自动删除关联的子表记录 | 删除某个用户,订单自动删除 |
on update cascade |
更新父表主键时,自动更新子表对应的外键 | 改变用户ID,订单中的用户ID也随之变 |
总结
方面 | 说明 |
---|---|
作用 | 保证两个表之间的关系数据完整性 |
依赖关系 | 引用的字段必须是被引用表的主键或唯一键 |
操作 | 支持级联删除/更新,保护数据一致性 |
多用场景 | 一对多关系(如订单与客户)、多对多关系的中介表设计等 |