自学内容网 自学内容网

MySQL 表的约束


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

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

1. 空属性

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

image-20241110222747540

2. 默认值

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

  • 当我们不设置默认值时,不写默认插入NULL,并且可以显式插入NULL
  • 当我们设置默认值后,不写插入默认值,并且可以显式插入NULL
  • 当我们设置默认值并且设置not null后,不写插入默认值,但不可以显式插入NULL
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;

image-20241111210535248

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

3. 列描述

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

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

image-20241111212017124

4. zerofill

CREATE TABLE t3 (a int, b int UNSIGNED, c int UNSIGNED ZEROFILL);
DESC t3;

image-20241111223237193

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

INSERT INTO t3 VALUES (1, 2, 3);
SELECT * FROM t3;

image-20241111223447757

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

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;

image-20241111223701247

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

SELECT * FROM t3 WHERE c = 33;

image-20241111223812544

SELECT c, hex(c) FROM t3;

image-20241111223954994

所以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)用来唯一的约束该字段里面的数据,不能重复,不能为空,一张表中最多只能有一个主键
  • 主键所在的列通常是整数类型

建一个带有主键的表

CREATE TABLE t4 (id INT PRIMARY KEY, name VARCHAR(20) NOT NULL);
DESC t4;

image-20241112165509332

主键对应的字段不能重复

INSERT INTO t4 VALUES (1, '张三');
INSERT INTO t4 VALUES (2, '张三');    -- ok
INSERT INTO t4 VALUES (1, '张三');    -- err

image-20241112165720869

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

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

image-20241112170202412

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

ALTER TABLE t4 ADD PRIMARY KEY(id);

image-20241112170329195

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


5.2 复合主键

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

CREATE TABLE t5 ( id INT, cId INT, other VARCHAR ( 20 ), PRIMARY KEY ( id, cId ) );
DESC t5;

image-20241112172044846

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

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一栏有值)
  • 自增长字段必须是整数
  • 一张表最多只能有一个自增长

建表

CREATE TABLE t6 ( id INT UNSIGNED PRIMARY KEY auto_increment, NAME VARCHAR ( 20 ) );
DESC t6;

image-20241112195110066

插入数据,自增

INSERT INTO t6 (NAME) VALUES('aaa');
INSERT INTO t6 (NAME) VALUES('bbb');
INSERT INTO t6 VALUES(100, 'ccc');
INSERT INTO t6 (NAME) VALUES('ddd');

image-20241112195448056

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

SELECT LAST_INSERT_ID();

image-20241112195726790

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

CREATE TABLE t7 ( id INT UNSIGNED PRIMARY KEY, cID INT UNSIGNED UNIQUE auto_increment);
DESC t7;

image-20241112200435726

6. 唯一键

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

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

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

CREATE TABLE t8 ( id INT UNSIGNED PRIMARY KEY, qq CHAR(20) UNIQUE);
DESC t8;

image-20241112211305979

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

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

image-20241112211545571

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

CREATE TABLE t9 ( id INT UNSIGNED PRIMARY KEY, qq CHAR(20) NOT NULL UNIQUE);
INSERT INTO t9 VALUES(1, NULL);

image-20241112211803291

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

7. 外键

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

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

比如我们想建下面的表

image-20241112222407589

主表(班级表):在数据库中建立的表格即Table,其中存在主键(primary key)用于与其它表相关联
从表(学生表):以主表的主键(primary key)值为外键 (Foreign Key)的表,可以通过外键与主表进行关联查询。从表与主表通过外键进行关联查询。

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


先建主表

CREATE TABLE myclass (id INT UNSIGNED PRIMARY KEY, name VARCHAR(24) NOT NULL);

再建从表,并定义外键

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;

image-20241112223013076

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

INSERT INTO myclass VALUES(1, '1班');
INSERT INTO myclass VALUES(2, '2班');
INSERT INTO myclass VALUES(3, '3班');
SELECT * FROM myclass;

image-20241112223603717

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

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

image-20241112223804740

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

DELETE FROM myclass WHERE id = 1;

image-20241112223925194


原文地址:https://blog.csdn.net/Suinnn/article/details/143735049

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!