千家信息网

MySQL约束

发表于:2025-01-23 作者:千家信息网编辑
千家信息网最后更新 2025年01月23日,约束也叫完整性约束(integrity constraint)什么是完整性?完整性是指数据库中存放的数据是有意义的、正确的什么是约束?为了保证数据的正确性和相容性,对关系模型提出的某些约束条件或者规则
千家信息网最后更新 2025年01月23日MySQL约束

约束也叫完整性约束(integrity constraint)
什么是完整性?
完整性是指数据库中存放的数据是有意义的、正确的
什么是约束?
为了保证数据的正确性和相容性,对关系模型提出的某些约束条件或者规则

注意:约束一般是作用于字段上的

约束有哪些?
非空、唯一、默认值、主键、外键、自增
语法:
字段名 字段类型 [not null|unique|default 默认值|auto_increment]
1、默认值
mysql> create table t6 (name varchar(10),sex char(10) default 'male');
mysql> insert into t6 values();
mysql> select * from t6;
+------+------+
| name | sex |
+------+------+
| NULL | male |
+------+------+
1 row in set (0.00 sec)
默认值:当用户向表中插入数据时,指定了该字段的值,那么就插入该值;否则就插入默认值。

修改已经存在的表中某个字段的默认值,两种方法
alter table 表名 modify 字段名 字段类型 default 默认值;
alter table 表名 alter 字段名 set default 默认值;
mysql> alter table t6 alter name set default 'tom';
mysql> insert into t6 values();
mysql> select * from t6;
+------+------+
| name | sex |
+------+------+
| NULL | male |
| tom | male |
+------+------+
2 rows in set (0.00 sec)
2、非空 not null
mysql> select * from t6 where name is null; //查询name字段为null的行
mysql> select * from t6 where name is not null; //查询name字段不为null的行
mysql> create table t7 (id int not null,name char(10));
mysql> insert into t7 values(); //会将不允许为空的id字段转换成0
mysql> select * from t7;
+----+------+
| id | name |
+----+------+
| 0 | NULL |
| 0 | NULL |
+----+------+
2 rows in set (0.00 sec)
mysql> alter table t7 modify name char(10) not null;
mysql> select * from t7; //字段类型为字符串型,非空约束会将空值转换为空字符串
+----+------+
| id | name |
+----+------+
| 0 | |
| 0 | |
+----+------+
2 rows in set (0.00 sec)
3、唯一 unique
mysql> create table t8 (id int unique,name char(10));
mysql> insert into t8 values(); //注意:唯一性约束对空值无效
mysql> insert into t8 values();
mysql> select * from t8;
+------+------+
| id | name |
+------+------+
| NULL | NULL |
| NULL | NULL |
+------+------+
2 rows in set (0.00 sec)
mysql> insert into t8 values(1,'tom');
mysql> insert into t8 values(1,'mary');
ERROR 1062 (23000): Duplicate entry '1' for key 'id'

mysql> alter table t8 modify name char(10) unique;
mysql> insert into t8 values(2,'mary');
mysql> insert into t8 values(3,'tom');
ERROR 1062 (23000): Duplicate entry 'tom' for key 'name'

4、自增 auto_increment
要求:
1)该字段必须是数值型
2)字段上要有唯一性索引或者主键
mysql> create table t9 (id int primary key auto_increment);
mysql> desc t9;
+-------+---------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
+-------+---------+------+-----+---------+----------------+
1 row in set (0.00 sec)
mysql> insert into t9 values(); //插入1
mysql> insert into t9 values(3); //插入3

几点说明:
1)当自增字段发生断档时,值会从最大值继续自增
2)当delete删除最大值时,下一个值仍然从删除之前的最大值继续自增
3)当truncate表时,值从1开始重新计算

5、主键 primary key
主键是表中的特殊字段,这个字段能够唯一的标识表中的每一条记录。
一张表最多只能有一个主键。
主键的用途:快速定位数据
主键需要满足的条件:非空且唯一
primary key == not null + unique
1)使用单个字段做主键
a、在字段后直接指定主键约束(列级约束,默认值为NULL)
mysql> create table t10 (id int primary key,age int,name char(10));
mysql> desc t10;
+-------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| age | int(11) | YES | | NULL | |
| name | char(10) | YES | | NULL | |
+-------+----------+------+-----+---------+-------+
mysql> insert into t10(id) values(1);
mysql> insert into t10(id) values(1);
ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
mysql> insert into t10 values();
mysql> insert into t10 values();
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
b、整张表的所有字段都定义完成之后再来指定主键(表级约束,默认值是0)
mysql> create table t11 (id int,name char(5),primary key(id));
mysql> desc t11;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | 0 | |
| name | char(5) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)
mysql> insert into t11 values();
mysql> insert into t11 values();
ERROR 1062 (23000): Duplicate entry '0' for key 'PRIMARY'
mysql> insert into t11 values(1,'hi');
mysql> select * from t11;
+----+------+
| id | name |
+----+------+
| 0 | NULL |
| 1 | hi |
+----+------+
2 rows in set (0.00 sec)
2)多个字段联合做主键
mysql> desc mysql.user \G //user和host字段联合做主键
*************************** 1. row ***************************
Field: Host
Type: char(60)
Null: NO
Key: PRI
Default:
Extra:
*************************** 2. row ***************************
Field: User
Type: char(16)
Null: NO
Key: PRI
Default:
Extra:
*************************** 3. row ***************************
Field: Password
Type: char(41)
Null: NO
Key:
Default:
Extra:

注意:联合主键只能在所有字段都定义完成之后,才能定义主键。
mysql> create table t12 (id int,name char(2),age int,primary key(id,name));
mysql> desc t12;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | 0 | |
| name | char(2) | NO | PRI | | |
| age | int(11) | YES | | NULL | |
+-------+---------+------+-----+---------+-------+
mysql> insert into t12(id) values(1);
mysql> select * from t12;
+----+------+------+
| id | name | age |
+----+------+------+
| 0 | | NULL |
| 1 | | NULL |
+----+------+------+
2 rows in set (0.00 sec)
mysql> insert into t12(name) values ('a');
mysql> select * from t12;
+----+------+------+
| id | name | age |
+----+------+------+
| 0 | | NULL |
| 0 | a | NULL |
| 1 | | NULL |
+----+------+------+
3 rows in set (0.00 sec)

6、外键 foreign key
外键:一个表的数据依赖于另一张表的主键列的数据,如果在主键列没有出现的值,是不能够出现在外键字段的。

主键和外键就像粘合剂,能够将多个表联系起来。


创建外键的条件:
1)存储引擎是innodb
2)相关联字段数据类型要一致
3)最好在外键列上建索引(目的就是为了减小扫描范围,不创建也可以,只是影响性能)

例子:
dept:部门表
emp :员工表
mysql> create table dept (dno int,dname char(10),primary key (dno));
mysql> create table emp (eno int,e_dno int,ename char(15),index(e_dno),foreign key (e_dno) references dept(dno));
向父表中插入数据
mysql> insert into dept values(1,'sa'),(2,'dba'),(3,'manager');
向子表中插入数据
mysql> select * from dept;
+-----+---------+
| dno | dname |
+-----+---------+
| 1 | sa |
| 2 | dba |
| 3 | manager |
+-----+---------+
3 rows in set (0.00 sec)

mysql> insert into emp values(100,3,'Tom');
mysql> select * from emp;
+------+-------+-------+
| eno | e_dno | ename |
+------+-------+-------+
| 100 | 3 | Tom |
+------+-------+-------+
1 row in set (0.00 sec)

mysql> insert into emp values(101,4,'Mary'); //反例:插入父表中不存在的部门号
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`up1`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`e_dno`) REFERENCES `dept` (`dno`))

mysql> delete from dept where dno=2;
mysql> delete from dept where dno=3;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails (`up1`.`emp`, CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`e_dno`) REFERENCES `dept` (`dno`))

小结:
1)子表中的数据依赖于父表,不能向子表中插入父表中不存在值
2)不能删除父表中被子表所依赖的记录

删除父表中被依赖的行的方法:
1)删除外键约束
2)指定级联操作的选项

on delete cascade:级联删除
on update cascade:级联更新
mysql> drop table emp;
mysql> create table emp (eno int,e_dno int,ename char(15),index(e_dno),foreign key (e_dno) references dept(dno) on delete cascade on update cascade); //完整的外键创建
mysql> insert into emp values(100,1,'Tom'),(101,3,'Mary'),(103,1,'Jack');
mysql> select * from dept;
+-----+---------+
| dno | dname |
+-----+---------+
| 1 | sa |
| 3 | manager |
+-----+---------+
2 rows in set (0.00 sec)

mysql> select * from emp;
+------+-------+-------+
| eno | e_dno | ename |
+------+-------+-------+
| 100 | 1 | Tom |
| 101 | 3 | Mary |
| 103 | 1 | Jack |
+------+-------+-------+
3 rows in set (0.00 sec)

mysql> delete from dept where dno=1;
Query OK, 1 row affected (0.02 sec)

mysql> select * from emp;
+------+-------+-------+
| eno | e_dno | ename |
+------+-------+-------+
| 101 | 3 | Mary |
+------+-------+-------+
1 row in set (0.00 sec)

mysql> update dept set dno=100 where dno=3;
Query OK, 1 row affected (0.07 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from emp;
+------+-------+-------+
| eno | e_dno | ename |
+------+-------+-------+
| 101 | 100 | Mary |
+------+-------+-------+
1 row in set (0.00 sec)
有了级联删除和级联修改选项,父表中的数据发生删除或者更新时,子表中相关数据也会发生相应的变化。

删除外键
alter table 表名 drop foreign key 外键的名字
mysql> show create table emp \G //红色字体为外键的名字
*************************** 1. row ***************************
Table: emp
Create Table: CREATE TABLE `emp` (
`eno` int(11) DEFAULT NULL,
`e_dno` int(11) DEFAULT NULL,
`ename` char(15) DEFAULT NULL,
KEY `e_dno` (`e_dno`),
CONSTRAINT `emp_ibfk_1` FOREIGN KEY (`e_dno`) REFERENCES `dept` (`dno`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8

mysql> alter table emp drop foreign key emp_ibfk_1;
mysql> show create table emp \G
*************************** 1. row ***************************
Table: emp
Create Table: CREATE TABLE `emp` (
`eno` int(11) DEFAULT NULL,
`e_dno` int(11) DEFAULT NULL,
`ename` char(15) DEFAULT NULL,
KEY `e_dno` (`e_dno`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


字段 数据 类型 最大 完整性 最大值 条件 联合 名字 唯一性 多个 方法 索引 部门 更新 查询 特殊 一致 作用 例子 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中文数据库提供同义词的 检察网络安全面临的挑战 网络安全 演练形式 计算机软件开发纠纷的级别管辖 网络安全学习重要性 阿尔法家拆单软件无法连接服务器 上海蛙扑网络技术有限公司游戏 旧版rust服务器如何秒造 开票机安全服务器地址 云服务器ecs哪家服务好 mysql数据库数据导出 网络安全提升服务方案 公司服务器被黑客入侵会被罚款吗 达梦数据库有限公司 iis 7.5 数据库 数据库设计由前端还是后端做 网络安全志愿者倡议书 工业企业数据库多少家企业 昆山网络技术咨询服务 孝感市凯维网络技术有限公司 sci检索中文数据库 管家婆服务器对网速要求 美国全球任意断网对网络安全 斗地主是什么软件开发的 电大数据库管理与维护作业 天地网络安全绘画 数据库接口在哪里查看 春考网络技术简单吗 软件开发技术招标书 图片转素描软件开发公司电话
0