MySQL表的约束:从基础到核心(附场景+案例)

⭐️个人主页:@小羊 ⭐️所属专栏:MySQL初阶 很荣幸您能阅读我的文章,诚请评论指点,欢迎欢迎 ~

目录

基础约束:控制字段的基础规则

空属性

  • 作用:限制字段不能为空(默认是NULL);

  • 坑点:空值无法参与运算(比如1+NULL结果还是NULL);

  • 案例:班级表的"班级名"不能空:

    sql 复制代码
    create table myclass(
      class_name varchar(20) not null, -- 必须填
      class_room varchar(10) not null
    );

默认值

  • 作用:字段没填值时,自动用预设值;

  • 案例:用户表的"性别"默认设为"男":

    sql 复制代码
    create table tt10(
      name varchar(20) not null,
      sex char(2) default '男' -- 没填则自动为"男"
    );
  • 小技巧:NOT NULLDEFAULT不用同时加(默认值本身不会空)。

列描述

  • 作用:给字段加"备注"(方便程序员理解);

  • 查看方式:用show create table 表名;才能看到(desc看不到);

  • 案例:

    sql 复制代码
    create table tt12(
      name varchar(20) not null comment '姓名',
      age tinyint unsigned default 0 comment '年龄'
    );

零填充

  • 作用:数字长度不够时,自动补0(仅显示效果,实际存储还是原数);
  • 案例:int(5) zerofill存1会显示00001
  • 注意:只改变显示,不改变实际存储的值。

核心约束:保证数据唯一性/关联性

主键

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

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


一般都是在使用表之前就要把主键确定下来。

  • 一张表中最多只能有一个主键,并不意味着一个表中的主键,只能添加给一列,一个主键可以被添加到一列,或多列上(复合主键)。

idcourse_id 有一个不冲突,就不会触发主键约束 ;只有 idcourse_id 同时冲突了,才会触发主键约束。

  • 作用:唯一标识一行数据,要求"非空+不重复";
  • 特点:一张表只能有1个主键,通常用整数类型;
  • 用法:
    • 单个字段主键:

      sql 复制代码
      create table tt13(
        id int unsigned primary key, -- 学号作为主键
        name varchar(20) not null
      );
    • 复合主键(多个字段联合唯一):

      sql 复制代码
      create table tt14(
        id int unsigned,
        course char(10),
        primary key(id, course) -- 学号+课程号联合唯一
      );

自增长

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

特点

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

案例:


在插入后获取上次插入的 AUTO_INCREMENT 的值(批量插入获取的是第一个值):

如何理解索引:

想象你在读一本上千页的编程教材,里面有各种编程概念、代码示例和项目案例。要是没有目录,想找"如何实现数据库索引"这样的知识点,就得从第一页开始一页页翻,特别费时间和精力。

有了目录就不一样了,它按章节和主题列出了重要内容的页码。你直接在目录里找到"数据库索引"相关章节的页码,就能快速翻到对应页面查看内容。

数据库里的索引就像书的目录,表中的数据好比书里的正文。索引给表中的数据构建了类似目录的结构,能让数据库系统快速找到想要的数据,查找效率大大提高。

  • 作用:配合主键,自动生成"递增的整数"(不用手动填);

  • 特点:必须是整数+索引字段+一张表只能有1个;

  • 案例:

    sql 复制代码
    create table tt21(
      id int unsigned primary key auto_increment, -- 自动从1开始递增
      name varchar(10) not null
    );
  • 小技巧:用last_insert_id()可获取最后一次自增的值。

唯一键

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

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

唯一键和主键的区别我们可以简单理解成,主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。

主键就像班级中同学的学号,是唯一且不能为空的;唯一键就像身份证号,也是唯一的,但可能会有同学还没来得及登记身份证号,所以可以为空。

sql 复制代码
mysql> create table student(
    -> id int unsigned unique, 
    -> name varchar(20)
    -> );
Query OK, 0 rows affected (0.11 sec)

mysql> insert into student values (111, '张三');
Query OK, 1 row affected (0.02 sec)

mysql> insert into student values (222, '李四');
Query OK, 1 row affected (0.01 sec)

不能重复,但可以为空:

sql 复制代码
mysql> insert into student values (222, '王五');
ERROR 1062 (23000): Duplicate entry '222' for key 'student.id'
mysql> insert into student (name) values ('王五');
Query OK, 1 row affected (0.01 sec)
  • 作用:保证字段值不重复(但允许为空,空值不参与唯一性比较);

  • 和主键的区别:主键是"标识唯一",唯一键是"业务唯一"(一张表可以有多个);

  • 案例:员工表的"工号"不能重复(但可以为空):

    sql 复制代码
    create table student(
      id char(10) unique, -- 学号唯一
      name varchar(10)
    );

外键

建立和维护数据库中主表和从表之间关联关系的一种约束。

外键约束主要定义在从表上 ,主表则必须 是有主键约束或唯一键约束。当定义外键后,要求外键列数据必须在主表的主键列存在或为NULL。

它是一个表中的一个或多个字段,其值对应于另一个表中的主键或唯一键。通过外键,可以确保相关表中的数据一致性和正确性,维护数据库表的引用完整性。

sql 复制代码
foreign key (字段名) references 主表(列) 

案例:

  • 先创建主键表:
sql 复制代码
mysql> create table class(
    -> id int unsigned primary key,
    -> name varchar(20) not null 
    -> );
Query OK, 0 rows affected (0.38 sec)
  • 再创建从表:
sql 复制代码
mysql> create table student(
    -> id int unsigned primary key,
    -> name varchar(20) not null,
    -> class_id int unsigned,
    -> foreign key (class_id) references class(id)
    -> );
Query OK, 0 rows affected (0.23 sec)
  • 插入合法数据:
sql 复制代码
mysql> insert into class values (1, 'C++班'), (2, 'Java班');
Query OK, 2 rows affected (0.05 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> insert into student values (111, '张三', '1'), (222, '李四', '2');
Query OK, 2 rows affected (0.03 sec)
Records: 2  Duplicates: 0  Warnings: 0
  • 不能插入主表主键列不存在的数据,但可以插入NULL:
sql 复制代码
mysql> insert into student values (333, '王五', '3');
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`d1`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`))
mysql> insert into student values (333, '王五', null);
Query OK, 1 row affected (0.00 sec)

如何理解外键约束:

  • 班级表:记录着每个班级的信息,其中"班级编号"是唯一标识每个班级的,它就像班级的身份证号,是班级表的主键 。比如有"1班""2班" ,每个班级对应一个独一无二的编号。
  • 学生表:用来记录每个学生的信息。学生是属于某个班级的,所以学生表中会有一个字段来表示学生所在班级,这个字段就可以设置为外键 。假设"学生表"里有个"所属班级编号"字段,它的值必须是"班级表"里已经存在的"班级编号" 。

如果没有外键约束,可能会出现这样的情况:在"学生表"里录入一个学生信息,把他的"所属班级编号"写成了一个不存在的编号,比如写成了"99班" ,可实际上"班级表"里根本没有这个班级。

但当我们在"学生表"的"所属班级编号"字段上设置了外键约束,并且这个外键约束关联到"班级表"的"班级编号"主键时,数据库就会进行检查。如果要插入一个学生信息,其"所属班级编号"在"班级表"里不存在,数据库就会拒绝这个插入操作,这样就能保证数据的一致性和准确性 。

再比如,如果"班级表"里删除了"3班"这个记录,要是没有外键约束,"学生表"里可能还存在标记为属于"3班"的学生记录,这就不合理了。但有了外键约束,我们可以设置当"班级表"里删除"3班"记录时,"学生表"里相关"3班"学生记录也跟着被删除(级联删除 ),或者把这些学生的"所属班级编号"设置为空(前提是允许为空 )等处理方式,从而维护两个表之间数据的关联和完整 。

  • 作用:关联两张表,保证从表的数据必须在主表中存在(避免无效数据);

  • 用法:主表要有主键/唯一键,从表通过外键关联;

  • 案例:学生表关联班级表(学生的班级ID必须是班级表中存在的):

    sql 复制代码
    -- 主表(班级表)
    create table myclass(
      id int primary key,
      name varchar(30) not null
    );
    -- 从表(学生表)
    create table stu(
      id int primary key,
      name varchar(30) not null,
      class_id int,
      foreign key(class_id) references myclass(id) -- 关联班级表的id
    );
  • 效果:插入学生时,class_id必须是myclass中存在的ID,否则插入失败。

约束怎么选?

  • 字段不能空→NOT NULL
  • 字段有默认值→DEFAULT
  • 唯一标识一行→PRIMARY KEY+AUTO_INCREMENT
  • 业务字段不能重复→UNIQUE
  • 两张表有关联→FOREIGN KEY

本篇文章的分享就到这里了,如果您觉得在本文有所收获,还请留下您的三连支持哦~

相关推荐
用户861782773651816 分钟前
MySQL 8.0从库宕机排查实录:中继日志膨胀引发的连锁故障复盘
mysql
Kapaseker1 小时前
一杯美式搞懂 Any、Unit、Nothing
android·kotlin
黄林晴1 小时前
你的 Android App 还没接 AI?Gemini API 接入全攻略
android
恋猫de小郭11 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
冬奇Lab12 小时前
PowerManagerService(上):电源状态与WakeLock管理
android·源码阅读
NineData16 小时前
NineData智能数据管理平台新功能发布|2026年1-2月
数据库·sql·数据分析
IvorySQL17 小时前
双星闪耀温哥华:IvorySQL 社区两项议题入选 PGConf.dev 2026
数据库·postgresql·开源
BoomHe18 小时前
Now in Android 架构模式全面分析
android·android jetpack
ma_king20 小时前
入门 java 和 数据库
java·数据库·后端
jiayou641 天前
KingbaseES 实战:审计追踪配置与运维实践
数据库