MySQL 表的约束

文章目录

  • [1. 空属性](#1. 空属性)
  • [2. 默认值](#2. 默认值)
  • [3. 列描述](#3. 列描述)
  • [4. zerofill](#4. zerofill)
  • [5. 主键](#5. 主键)
    • [5.1 主键](#5.1 主键)
    • [5.2 复合主键](#5.2 复合主键)
    • [5.3 自增长](#5.3 自增长)
  • [6. 唯一键](#6. 唯一键)
  • [7. 外键](#7. 外键)

表的约束(Table Constraints)是数据库管理系统中 用于维护数据库完整性的规则 。它们定义了表中数据必须遵循的限制条件,以确保数据的准确性和可靠性。

表的约束很多,这里主要介绍如下几个: null/not null,default, comment, zerofill,primary key,auto_increment,unique key 。

1. 空属性

  • 两个值:null(空)和not null(不为空)
  • 数据库默认字段基本都是字段可以为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算。
sql 复制代码
CREATE TABLE t1 (name VARCHAR(40) NOT NULL, other VARCHAR(40));
INSERT INTO t1 VALUES('张三', NULL);    -- ok
INSERT INTO t1 VALUES(NULL, NULL);      -- err

2. 默认值

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

  • 当我们不设置默认值时,不写默认插入NULL,并且可以显式插入NULL
  • 当我们设置默认值后,不写插入默认值,并且可以显式插入NULL
  • 当我们设置默认值并且设置not null后,不写插入默认值,但不可以显式插入NULL
sql 复制代码
CREATE TABLE t2(name VARCHAR(40) DEFAULT '张三' NOT NULL);
INSERT INTO t2 VALUES(NULL);    -- err
INSERT INTO t2 VALUES();        -- ok
INSERT INTO t2 VALUES('李四');  -- ok
SELECT * FROM t2;

注:虽然NOT NULLDEFAULT可以同时设置,但是一般不需要同时出现,因为 DEFAULT本身有默认值,不会为NULL

3. 列描述

注释,用来给程序员或DBA来进行了解。 可以使用show查看

sql 复制代码
CREATE TABLE t2(name VARCHAR(40) DEFAULT '张三' NOT NULL COMMENT '这是姓名!!!');

4. zerofill

sql 复制代码
CREATE TABLE t3 (a int, b int UNSIGNED, c int UNSIGNED ZEROFILL);
DESC t3;

如果宽度小于设定的宽度,自动填充0。

sql 复制代码
INSERT INTO t3 VALUES (1, 2, 3);
SELECT * FROM t3;

如果宽度大于设定的宽度,显示原来的数字

sql 复制代码
ALTER TABLE t3 MODIFY c int(3) UNSIGNED ZEROFILL;
INSERT INTO t3 VALUES (1, 2, 33);
INSERT INTO t3 VALUES (1, 2, 333);
INSERT INTO t3 VALUES (1, 2, 3333);
SELECT * FROM t3;

这只是最后显示的结果,在MySQL中实际存储的还是原本插入的值

sql 复制代码
SELECT * FROM t3 WHERE c = 33;
sql 复制代码
SELECT c, hex(c) FROM t3;

所以zerofill只是设置一种格式化输出而已。


注:看第一个图,a列是 int(11),而b列和c列是int(10), 这是因为a列是INT,b和c是UNSIGNED INT,int和unsigned int能表示4,294,967,296个数字,刚好是10位,多了一个符号位是11。

5. 主键

5.1 主键

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

建一个带有主键的表

sql 复制代码
CREATE TABLE t4 (id INT PRIMARY KEY, name VARCHAR(20) NOT NULL);
DESC t4;

主键对应的字段不能重复

sql 复制代码
INSERT INTO t4 VALUES (1, '张三');
INSERT INTO t4 VALUES (2, '张三');    -- ok
INSERT INTO t4 VALUES (1, '张三');    -- err

删除主键,删除后,id列可以重复

sql 复制代码
ALTER TABLE t4 DROP PRIMARY KEY;
INSERT INTO t4 VALUES (1, '李四');		-- ok
SELECT * FROM t4;

可以再次追加主键,不过会检查该列,如果有重复的话,则不能添加主键

sql 复制代码
ALTER TABLE t4 ADD PRIMARY KEY(id);

需要删除重复行才可以加主键,所以一般不要在表中已经有数据的情况下随便增加删除主键。


5.2 复合主键

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

sql 复制代码
CREATE TABLE t5 ( id INT, cId INT, other VARCHAR ( 20 ), PRIMARY KEY ( id, cId ) );
DESC t5;

在上面的例子中,我们将id和cId字段一起声明为主键。这样就可以保证每个用户的id和cId的组合是唯一的。

sql 复制代码
INSERT INTO t5 VALUES(1, 100, 'aaa');
INSERT INTO t5 VALUES(2, 100, 'aaa');
INSERT INTO t5 VALUES(2, 101, 'aaa');
INSERT INTO t5 VALUES(3, 102, 'aaa');
INSERT INTO t5 VALUES(3, 102, 'aaa');     -- err

5.3 自增长

自增长(auto_increment): 当对应的字段,不给值,会自动的被系统触发,系统会从当前字段中已经有的最大值+1操作,得到一个新的不同的值。通常给主键添加

特点:

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

建表

sql 复制代码
CREATE TABLE t6 ( id INT UNSIGNED PRIMARY KEY auto_increment, NAME VARCHAR ( 20 ) );
DESC t6;

插入数据,自增

sql 复制代码
INSERT INTO t6 (NAME) VALUES('aaa');
INSERT INTO t6 (NAME) VALUES('bbb');
INSERT INTO t6 VALUES(100, 'ccc');
INSERT INTO t6 (NAME) VALUES('ddd');

可以通过LAST_INSERT_ID()来获取最近一次被设置为自增的列插入的值

sql 复制代码
SELECT LAST_INSERT_ID();

自增一般只设置给主键,若想设置给其它列,需要设置为UNIQUE

sql 复制代码
CREATE TABLE t7 ( id INT UNSIGNED PRIMARY KEY, cID INT UNSIGNED UNIQUE auto_increment);
DESC t7;

6. 唯一键

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

  • 唯一键允许为空,而且可以多个为空,空字段不做唯一性比较。
  • 主键更多的是标识唯一性的。而唯一键更多的是保证在业务上,不要和别的信息出现重复。 两者是互相配合的

建表,id已经是主键了,这时候有qq号,也应该保证唯一性,所以设置为UNIQUE

sql 复制代码
CREATE TABLE t8 ( id INT UNSIGNED PRIMARY KEY, qq CHAR(20) UNIQUE);
DESC t8;

可以插入为空,但不能重复

sql 复制代码
INSERT INTO t8 VALUES(1, NULL);
INSERT INTO t8 VALUES(2, NULL);
INSERT INTO t8 VALUES(3, '372536468');
INSERT INTO t8 VALUES(4, '372536468');    -- err

当然也可以修改不能插入空值

sql' 复制代码
CREATE TABLE t9 ( id INT UNSIGNED PRIMARY KEY, qq CHAR(20) NOT NULL UNIQUE);
INSERT INTO t9 VALUES(1, NULL);

一般而言,我们建议将主键设计成为和当前业务无关的字段,这样,当业务调整的时候,我们可以尽量不会对主键做过大的调整。

7. 外键

外键用于定义主表和从表之间的关系:

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

比如我们想建下面的表

主表(班级表):在数据库中建立的表格即Table,其中存在主键(primary key)用于与其它表相关联

从表(学生表):以主表的主键(primary key)值为外键 (Foreign Key)的表,可以通过外键与主表进行关联查询。从表与主表通过外键进行关联查询。

从表数据依赖于主表,一般最后查询数据时把主表与从表进行关联查询。


先建主表

sql 复制代码
CREATE TABLE myclass (id INT UNSIGNED PRIMARY KEY, name VARCHAR(24) NOT NULL);

再建从表,并定义外键

sql 复制代码
CREATE TABLE stu (
  id INT UNSIGNED PRIMARY KEY,
  NAME VARCHAR ( 24 ) NOT NULL,
  class_id INT UNSIGNED,
  FOREIGN KEY ( class_id ) REFERENCES myclass ( id ) 
);

DESC stu;

向班级表(主表)中插入数据

sql 复制代码
INSERT INTO myclass VALUES(1, '1班');
INSERT INTO myclass VALUES(2, '2班');
INSERT INTO myclass VALUES(3, '3班');
SELECT * FROM myclass;

向学生表(从表)中插入数据

sql 复制代码
INSERT INTO stu VALUES(1, '张三', 1);
INSERT INTO stu VALUES(2, '李四', NULL);
INSERT INTO stu VALUES(3, '王五', 1111);		-- err, 有主键约束
SELECT * FROM stu;

此时如果在班级表中删除1班,会报错,因为已经有学生表在使用该id了。

sql 复制代码
DELETE FROM myclass WHERE id = 1;
相关推荐
苹果醋31 小时前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
了一li1 小时前
Qt中的QProcess与Boost.Interprocess:实现多进程编程
服务器·数据库·qt
码农君莫笑2 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
别致的影分身2 小时前
使用C语言连接MySQL
数据库·mysql
过过过呀Glik2 小时前
在 Ubuntu 上安装 MySQL 的详细指南
mysql·ubuntu
京东零售技术4 小时前
“慢”增长时代的企业数据体系建设:超越数据中台
数据库
sdaxue.com4 小时前
帝国CMS:如何去掉帝国CMS登录界面的认证码登录
数据库·github·网站·帝国cms·认证码
o(╥﹏╥)5 小时前
linux(ubuntu )卡死怎么强制重启
linux·数据库·ubuntu·系统安全
阿里嘎多学长5 小时前
docker怎么部署高斯数据库
运维·数据库·docker·容器
Yuan_o_5 小时前
Linux 基本使用和程序部署
java·linux·运维·服务器·数据库·后端