MySQL表的约束

一、空属性

两个值:null(默认的)和not null(不为空)

数据库默认字段基本都是字段为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算

案例:

创建一个班级表,包含班级名和所在的教室。

如果班级没有名字,就不知道在哪个班级

如果教室名字为空,就不知道在哪上课

所以对于班级和教室列,其不能为空

mysql> create table tt1(class_id int not null,classroom varchar(10) not null);

Query OK, 0 rows affected (0.08 sec)

mysql> desc tt1;

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

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

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

| class_id | int | NO | | NULL | |

| classroom | varchar(10) | NO | | NULL | |

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

2 rows in set (0.00 sec)

mysql> insert into tt1 value(1,'行远楼');

Query OK, 1 row affected (0.02 sec)

mysql> insert into tt1 value(1);

ERROR 1136 (21S01): Column count doesn't match value count at row 1

二、默认值

默认值:某一种数据会经常性的出现某个具体的值,可以一开始就指定好,在需要真实数据的时候,用户可选择性的使用默认值。

mysql> alter table tt1 add column lesson char(4) default '自习';

Query OK, 0 rows affected (0.05 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> desc tt1;

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

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

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

| class_id | int | NO | | NULL | |

| classroom | varchar(10) | NO | | NULL | |

| lesson | char(4) | YES | | 自习 | |

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

3 rows in set (0.00 sec)

mysql> select * from tt1;

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

| class_id | classroom | lesson |

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

| 1 | 行远楼 | 自习 |

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

1 row in set (0.00 sec)

三、列描述

列描述:comment,没有实际含义,专门用来描述字段,类似于列的注释

mysql> alter table tt1 add column teacher char(5) default '无' comment '老师';

Query OK, 0 rows affected (0.06 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> desc tt1;

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

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

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

| class_id | int | NO | | NULL | |

| classroom | varchar(10) | NO | | NULL | |

| lesson | char(4) | YES | | 自习 | |

| teacher | char(5) | YES | | 无 | |

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

4 rows in set (0.00 sec)

通过desc是查看不到注释信息的,得通过show

mysql> show create table tt1\G

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

Table: tt1

Create Table: CREATE TABLE `tt1` (

`class_id` int NOT NULL,

`classroom` varchar(10) NOT NULL,

`lesson` char(4) DEFAULT '自习',

`teacher` char(5) DEFAULT '无' COMMENT '老师'

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci

1 row in

四、主键

主键:primary key用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键,主键所在的列通常是整数类型。

案例:

创建表的时候直接在字段上指定主键

mysql> create table tt2(id int unsigned primary key comment '学号不能为空',

-> name varchar(20) not null);

Query OK, 0 rows affected (0.07 sec)

mysql> desc tt2;

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

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

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

| id | int unsigned | NO | PRI | NULL | |

| name | varchar(20) | NO | | NULL | |

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

2 rows in set (0.00 sec)

mysql> insert into tt2 value(1,'张三');

Query OK, 1 row affected (0.02 sec)

mysql> insert into tt2(name) value('张三');

ERROR 1364 (HY000): Field 'id' doesn't have a default value

mysql> insert into tt2 value(1,'张三');

ERROR 1062 (23000): Duplicate entry '1' for key 'tt2.PRIMARY'

删除主键&&追加主键

mysql> alter table tt2 drop primary key;

Query OK, 1 row affected (0.18 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> desc tt2;

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

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

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

| id | int unsigned | NO | | NULL | |

| name | varchar(20) | NO | | NULL | |

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

2 rows in set (0.00 sec)

mysql> alter table tt2 add primary key(id);

Query OK, 0 rows affected (0.16 sec)

Records: 0 Duplicates: 0 Warnings: 0

mysql> desc tt2;

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

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

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

| id | int unsigned | NO | PRI | NULL | |

| name | varchar(20) | NO | | NULL | |

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

2 rows in set (0.00 sec)

复合主键

创建表的时候,在所有字段以后,使用primary key(主键字段列表)来创建主键,如果有多个字段作为主键,可以使用复合主键。

mysql> create table tt3( id int unsigned, course char(10) ,score tinyint unsigned default 60 , primary key (id,course));

Query OK, 0 rows affected (0.20 sec)

mysql> desc tt3;

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

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

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

| id | int unsigned | NO | PRI | NULL | |

| course | char(10) | NO | PRI | NULL | |

| score | tinyint unsigned | YES | | 60 | |

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

3 rows in set (0.00 sec)

mysql> insert into tt3 value(1,'高数',40);

Query OK, 1 row affected (0.05 sec)

mysql> insert into tt3 value(1,'大物',40);

Query OK, 1 row affected (0.01 sec)

mysql> insert into tt3 value(1,'高数',40);

ERROR 1062 (23000): Duplicate entry '1-高数' for key 'tt3.PRIMARY'

五、自增长

auto_increment:当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常会搭配主键一起使用,作为逻辑主键

自增长的特点:

  • 任何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
  • 自增长字段必须是整数
  • 一张表最多只能有一个自增长

mysql> create table tt4(

-> id int unsigned primary key auto_increment,

-> name varchar(10) not null default ''

-> );

Query OK, 0 rows affected (0.09 sec)

mysql> insert into tt4(name) value('a');

Query OK, 1 row affected (0.02 sec)

mysql> insert into tt4(name) value('b');

Query OK, 1 row affected (0.02 sec)

mysql> select * from tt4;

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

| id | name |

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

| 1 | a |

| 2 | b |

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

2 rows in set (0.00 sec)

索引:

数据库索引是一种用于提高数据查询效率的数据结构,可以把它理解为书籍的目录。没有索引时,数据库可能需要逐行扫描整张表,才能找到符合条件的数据;建立索引后,数据库可以利用索引结构快速定位目标记录,减少需要扫描的数据量。以 MySQL 的 InnoDB 引擎为例,常见索引采用 B+ 树组织数据,主键索引的叶子节点存储完整的行数据,二级索引的叶子节点存储索引列的值和对应的主键值。当查询的列没有合适的索引时,数据库通常需要全表扫描;但即使存在索引,MySQL 优化器也会根据查询条件和成本决定是否使用索引。需要注意,索引能够提高查询效率,但也会占用额外的存储空间,并增加插入、删除和更新数据时维护索引的开销。

六、唯一键

一张表中往往有很多字段需要唯一性,数据不能重复,但是一张表中只能有一个主键:唯一键就可以解决表中有多个字段需要唯一性约束的问题。

唯一键的本质和主键差不多,唯一键允许为空,而且可以多个位空,空字符不做唯一性比较。

  • 主键: 每条记录必须有一个稳定、唯一的标识。

  • 唯一键: 某个业务字段确实不允许重复时,使用唯一约束保证数据正确性。

例:

mysql> create table tt5(

-> id char(10) unique ,

-> name varchar(10)

-> );

Query OK, 0 rows affected (0.10 sec)

mysql> insert into tt5 values('01','aaa');

Query OK, 1 row affected (0.03 sec)

mysql> insert into tt5 values('02','aaa');

Query OK, 1 row affected (0.02 sec)

mysql> insert into tt5 values('01','bbb');

ERROR 1062 (23000): Duplicate entry '01' for key 'tt5.id'

七、外键

外键用于定义主表和从表之间的关系:外键约束主要定义在从表上,主表则必须是有主键约束或者unique约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为null

语法:

foreign key (字段名)references 主表(列)

案例:

mysql> create table myclass(

-> id int,

-> name varchar(30) not null comment '班级名',

-> primary key(id)

-> );

Query OK, 0 rows affected (0.09 sec)

mysql> create table stu(

-> id int primary key,

-> name varchar(30) not null comment '学生名',

-> class_id int,

-> foreign key(class_id) references myclass(id)

-> );

插入两个班级

mysql> insert into myclass value(1,'2401');

Query OK, 1 row affected (0.01 sec)

mysql> insert into myclass value(2,'2402');

Query OK, 1 row affected (0.02 sec)

插入两个学生

mysql> insert into stu value(1,'wtyh',1);

Query OK, 1 row affected (0.03 sec)

mysql> insert into stu value(2,'djh',2);

Query OK, 1 row affected (0.01 sec)

插入第三个学生,由于主表无该班级,所以插入失败

mysql> insert into stu value(3,'whx',3);

ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`school_2`.`stu`, CONSTRAINT `stu_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `myclass` (`id`))

如何理解外键约束

外键约束用于维护关联表之间的引用完整性。例如,学生表中的 class_id 引用班级表的 id,那么学生所属的班级必须存在。MySQL 会在插入、更新或删除相关数据时检查外键约束,防止出现无效的关联关系。

相关推荐
Crayon Lin1 小时前
Milvus向量数据库入门
数据库·milvus
cspttty1 小时前
2027校招准备:数学与应用数学专业如何补齐管理咨询的业务、分析与表达能力
大数据·数据库
曹牧1 小时前
C#:字符串占位符与值数量不一致
开发语言·数据库·c#
2301_32241428041 小时前
基于SSM框架的在线考试管理系统的设计与实现14750-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·redis·mysql·tomcat·maven·mybatis·ssm
小马不起床1 小时前
Django 后端实战指南_14:门店、省份、用户门店关系查询接口
数据库·django·sqlite
我星期八休息2 小时前
Redis 的原理和使用(2)
前端·数据库·redis·python·mysql·缓存·bootstrap
betazhou2 小时前
Apache Seatunnel 抽取SQL server实时同步到Oracle(四)
数据库·oracle·apache·sql server·seatunnel
l1t2 小时前
DeepSeek总结的PostgreSQL 的 MVCC 很糟。其他所有的也一样。第1部分
数据库·postgresql
川石课堂软件测试2 小时前
JMeter异步接口测试实战
数据库·python·jmeter·mysql·kubernetes·测试用例·prometheus