约束用于确保数据库的数据满足特定的商业规则。
在Mysql
中,约束包括: not null
、unique
、primary key
、foreign key
、 和 check
五种.
字段名 字段类型 primary key (表示该字段为主键)
用于唯一的标示表行的数据,当定义主键约束后,该列不能重复
primary key
不能重复而且不能为null
字段名primakry key
primary key(列名)
-- id name email
CREATE TABLE t17
(id INT PRIMARY KEY, -- 表示id列是主键
`name` VARCHAR(32),
email VARCHAR(32));
-- 主键列的值是不可以重复
INSERT INTO t17
VALUES(1, 'jack', '[email protected]');
INSERT INTO t17
VALUES(2, 'tom', '[email protected]');
INSERT INTO t17
VALUES(1, 'cc', '[email protected]'); -- 报错
-- primary key不能重复而且不能为 null。
INSERT INTO t17
VALUES(NULL, 'cc', '[email protected]');
-- 一张表最多只能有一个主键, 但可以是复合主键(比如 id+name)
CREATE TABLE t18
(id INT PRIMARY KEY, -- 表示id列是主键
`name` VARCHAR(32), PRIMARY KEY -- 错误的
email VARCHAR(32));
-- 演示复合主键 (id 和 name 做成复合主键)
CREATE TABLE t18
(id INT ,
`name` VARCHAR(32),
email VARCHAR(32),
PRIMARY KEY (id, `name`) -- 这里就是复合主键
);
INSERT INTO t18
VALUES(1, 'tom', '[email protected]');
INSERT INTO t18
VALUES(1, 'jack', '[email protected]');
INSERT INTO t18
VALUES(1, 'tom', '[email protected]'); -- 这里就违反了复合主键
-- 主键的指定方式 有两种
-- 1. 直接在字段名后指定:字段名 primakry key
-- 2. 在表定义最后写 primary key(列名);
CREATE TABLE t19
(id INT ,
`name` VARCHAR(32) PRIMARY KEY,
email VARCHAR(32)
);
CREATE TABLE t20
(id INT ,
`name` VARCHAR(32) ,
email VARCHAR(32),
PRIMARY KEY(`name`) -- 在表定义最后写 primary key(列名)
);
-- 使用desc 表名,可以看到primary key的情况
DESC t20 -- 查看 t20表的结果,显示约束的情况
如果在列上定义了not null
,那么当插入数据时,必须为列提供数据。
字段名 字段类型 not null
当定义了唯一约束后,该列值是不能重复的。
字段名 字段类型 unique
not null
,则unique
字段可以有多个nullunique
字段CREATE TABLE t21
(id INT UNIQUE , -- 表示 id 列是不可以重复的.
`name` VARCHAR(32) ,
email VARCHAR(32)
);
INSERT INTO t21
VALUES(1, 'jack', '[email protected]');
INSERT INTO t21
VALUES(1, 'tom', '[email protected]');
-- 1. 如果没有指定 not null , 则 unique 字段可以有多个null
-- 如果一个列(字段), 是 unique not null 使用效果类似 primary key
INSERT INTO t21
VALUES(NULL, 'tom', '[email protected]');
SELECT * FROM t21;
-- 2. 一张表可以有多个unique字段
CREATE TABLE t22
(id INT UNIQUE , -- 表示 id 列是不可以重复的.
`name` VARCHAR(32) UNIQUE , -- 表示name不可以重复
email VARCHAR(32)
);
DESC t22
用于定义主表和从表之间的关系:
unique
约束null
-- 创建 主表 my_class
CREATE TABLE my_class (
id INT PRIMARY KEY , -- 班级编号
`name` VARCHAR(32) NOT NULL DEFAULT '');
-- 创建 从表 my_stu
CREATE TABLE my_stu (
id INT PRIMARY KEY , -- 学生编号
`name` VARCHAR(32) NOT NULL DEFAULT '',
class_id INT , -- 学生所在班级的编号
-- 下面指定外键关系
FOREIGN KEY (class_id) REFERENCES my_class(id))
-- 测试数据
INSERT INTO my_class
VALUES(100, 'java'), (200, 'web');
INSERT INTO my_class
VALUES(300, 'php');
SELECT * FROM my_class;
INSERT INTO my_stu
VALUES(1, 'tom', 100);
INSERT INTO my_stu
VALUES(2, 'jack', 200);
INSERT INTO my_stu
VALUES(4, 'mary', 400); -- 这里会失败...因为400班级不存在
INSERT INTO my_stu
VALUES(5, 'king', NULL); -- 可以, 外键 没有写 not null
SELECT * FROM my_class;
-- 一旦建立主外键的关系,数据不能随意删除了
DELETE FROM my_class
WHERE id = 100;
用于强制行数据必须满足的条件,假定在sal
列上定义了check
约束
并要求sal
列值在1000 \~2000
之间,如果不在1000\~2000
之间就会提示出错
注意:oracle
和 sql server
均支持check
,但是mysql5.7
目前还不支持check
,只做语法校验,但不会生效。
-- mysql5.7目前还不支持check ,只做语法校验,但不会生效
-- 了解
-- 学习 oracle, sql server, 这两个数据库是真的生效.
-- 测试
CREATE TABLE t23 (
id INT PRIMARY KEY,
`name` VARCHAR(32) ,
sex VARCHAR(6) CHECK (sex IN('man','woman')),
sal DOUBLE CHECK ( sal > 1000 AND sal < 2000)
);
-- 添加数据
INSERT INTO t23
VALUES(1, 'jack', 'mid', 1);
SELECT * FROM t23;
一般来说自增长是和primary key
配合使用的
自增长也可以单独使用[但是需要配合一个unique
]
自增长修饰的字段为整数型的(虽然小数也可以但是非常非常少这样使用)
自增长默认从1开始,也可以通过如下命令修改alter table 表名auto_increment = 新的开始值;
如果你添加数据时,给自增长字段(列)指定的有值,则以指定的值为准
如果指定了自增长,一般来说,就按照自增长的规则(从指定的值开始,再自增长) 来添加数据
-- 创建表
CREATE TABLE t24
(id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(32)NOT NULL DEFAULT '',
`name` VARCHAR(32)NOT NULL DEFAULT '');
DESC t24
-- 测试自增长的使用
INSERT INTO t24
VALUES(NULL, '[email protected]', 'tom'); -- 没有给值,自动维护,id自增长
INSERT INTO t24
(email, `name`) VALUES('[email protected]', 'cc');
-- 修改默认的自增长开始值
ALTER TABLE t25 AUTO_INCREMENT = 100
CREATE TABLE t25
(id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(32)NOT NULL DEFAULT '',
`name` VARCHAR(32)NOT NULL DEFAULT '');
INSERT INTO t25
VALUES(NULL, '[email protected]', 'mary');
INSERT INTO t25
VALUES(666, '[email protected]', 'cc');
SELECT * FROM t25;