文章目录
- [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 NULL
和 DEFAULT
可以同时设置,但是一般不需要同时出现,因为 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;