``# MySQL 约束
就是使用一些规则限制数据,保证数据合法性/正确性。从而满足需求。
-- 分类:
1. 行级约束(对某一列进行限制)
1.1 NULL NOT NULL 非空约束
1.2 UNIQUE 唯一性约束/索引
1.3 DEFAULT 默认约束(设置默认数据)
1.4 PRIMARY KEY 主键约束(重要)
2. 表级约束
2.1 PRIMARY KEY(联合主键) 位置: 在最后一个列的后面使用
2.2 FOREIGN KEY 外键约束(维护多表关系的)
NULL 表示列的数据可以为null值。
NOT NULL 表示列的数据不能为null值。
CREATE TABLE a(
id INT NULL,
name VARCHAR(10)
);
SELECT * FROM a;
DELETE FROM a;
INSERT INTO a (id) VALUES (1);
INSERT INTO a (name) VALUES ('aaa');
-- 在表结构创建好的前提下, 修改id name这个列的数据不能为null
DESC b;
ALTER TABLE a MODIFY id INT NOT NULL;
ALTER TABLE a MODIFY name VARCHAR(10) NOT NULL;
CREATE TABLE b(
id INT NOT NULL,
name VARCHAR(10) NOT NULL
);
唯一性约束/索引(是数据结构BTree)。
在一张表里面使用多次UNIQUE修饰多个列。
列的数据不可重复。
DROP TABLE a;
DROP TABLE b;
CREATE TABLE a(
id INT NOT NULL,
name VARCHAR(10)
);
INSERT INTO a (id,name) VALUES (1,'jim');
INSERT INTO a (id,name) VALUES (2,'tom');
INSERT INTO a (name) VALUES ('安琪拉');
SELECT * FROM a;
DELETE FROM a;
-- 保证id数据唯一性
DESC a;
ALTER TABLE a MODIFY id INT NULL;
ALTER TABLE a MODIFY name VARCHAR(10) NOT NULL UNIQUE;
给列设置默认值。
CREATE TABLE a(
id INT NOT NULL UNIQUE,
name VARCHAR(10) NOT NULL,
gender char(1)
);
INSERT INTO a (id,name) VALUES (2,'jim');
-- 新增的时候 没有提交gender的数据 默认设置 '男'
ALTER TABLE a MODIFY gender char(1) DEFAULT '男'
DESC a;
SELECT * FROM a;
-- INSERT INTO employee (id,name,dept,job,leader) VALUES (1003,'张三q111','研发部','普通员工','king');
-- -- UPDATE employee SET age=20,update_time=now() WHERE id=1002;
UPDATE employee SET age=30 WHERE id=1003;
SELECT * FROM employee;
DESC sys_user;
既可以是行级约束,又可以是表级约束。自带索引的。
1. 一张表里面只能使用1次 PRIMARY KEY
2. 使用 PRIMARY KEY 修饰的列 一般称为 "主键列"
3. 主键列的数据: 非空+唯一
4. 理论上任意一个列都可以作为主键列。实际开发中,一般都是id。 int bigint
5. 为什么要使用主键约束?
1. 保证记录唯一性。
2. 满足表设计的3大范式。
2.1 第一范式: 保证列的原子性 列不可再分的原则。
收货地址: address 河南省郑州市高新区
这个地址可以再分的 provice city area
2.2 第二范式: 在满足第一范式前提下,保证行记录的唯一性。 建议使用主键列。
2.3 第3范式: 在满足第2范式前提下,减少列/数据的冗余。排除外键列的数据。
自增
-- PRIMARY KEY
CREATE TABLE a(
id INT PRIMARY KEY, -- 行级约束
name VARCHAR(20)
);
INSERT INTO a (id,name) VALUES (1001,'jim');
INSERT INTO a (name) VALUES ('lucy4');
-- 新增的时候 每次都要自己维护id的唯一性
-- 保证id数据唯一性?
-- 1. mysql服务器,id自己自增(使用居多) 要求 列必须是主键约束/整数类型
-- 2. java程序控制 提供唯一的数据 作为id的数据
-- 需求: 设置id自增 auto_increment
-- 默认从1开始 自增的步长 1 当然可以修饰自增的初始值以及步长
-- ALTER TABLE a MODIFY id INT auto_increment;
-- 获得上一次自增的id数据
-- SELECT LAST_INSERT_ID();
-- 修改自增的初始值或者步长
-- ALTER TABLE a auto_increment 2001;
-- SET auto_increment_increment=1;
SELECT * FROM a;
DESC a;
CREATE TABLE b (
id BIGINT(10) PRIMARY KEY auto_increment , -- 行级约束
name VARCHAR(20)
);
-- 错误的 主键约束只有1个
CREATE TABLE e (
id BIGINT(10) PRIMARY KEY auto_increment , -- 行级约束
name VARCHAR(20) PRIMARY KEY
);
CREATE TABLE c (
id BIGINT(10) auto_increment,
name VARCHAR(20),
PRIMARY KEY(id) -- 表级约束
);
联合主键
-- 使用navicat可以点击多次主键 意味着表里面有联合主键
-- 联合主键: 必须使用表级约束编写
-- 多个列作为一个主键列体现
-- 一般出现的场景: 在中间表里面。
CREATE TABLE demo(
id int,
name VARCHAR(20),
PRIMARY KEY (id,name) -- 表级约束 联合主键
);
INSERT INTO demo (id,name) VALUES (1,'a'),(1,'b');
SELECT * FROM demo;
uuid()
CREATE TABLE a(
id VARCHAR(255) PRIMARY KEY,
age INT
);
DESC a;
-- ALTER TABLE a MODIFY id VARCHAR(255) auto_increment;
-- 问题: id是字符类型,保证数据的唯一性? 不能自增了
-- 1.java程序提交唯一的id
-- 2.mysql服务: UUID() UUID_SHORT()
-- uuid: 128位 由16进制的字符组成的串
-- SELECT UUID(),UUID(),UUID(),UUID();
-- SELECT UUID_SHORT();
-- 雪花算法
INSERT INTO a (id,age) VALUES (UUID(),10),(UUID(),20);
INSERT INTO a (id,age) VALUES (UUID_SHORT(),10),(UUID_SHORT(),20);
SELECT * FROM a;
外键约束,自带索引。
维护多张表的关系。
虽然我们讲解了 FOREIGN KEY ,但是开发中禁止使用的。
在开发中,开发互联网项目。数据量很大的
自己练习,毕业设计,项目(几百人) 完全可以使用....
外键列很重要,仅仅是一个普通列作为外键列。
重点: 普通的列维护表关系,把普通列看成外键列。
1. 在一张表里面,可以使用多次 FOREIGN KEY 修饰多个列。
2. 使用 FOREIGN KEY修饰的列,称为"外键列"。一张表中,外键列可以有多个的。
3. 外键列的数据不能对于设置。外键列的数据要严格参照另外一张表的主键列的数据。
4. 主表与从表之间关系。有外键列在的表,称为"从表/子表"。 外键列的数据参照的表就是"主表/基表"。
从表里面外键列的数据严格参照主表里面主键列的数据。
5.外键列的数据类型与主表的主键列的数据类型一致。
意义:
保证数据安全性。 性能低。
要使用外键约束,必须要保证数据库存储引擎是InnoDB。
-- 目前在cart表里面 新增新的列 uid
-- 假设是外键列。我们是没有添加外键约束的。
-- 所有对于目前的uid的数据,随意给值。
-- 这种操作是不对的。没有满足规则。
-- 规则: 外键列数据严格参照用户表的id的数据。
-- 想实现以上规则,必须新增外键约束。
-- 外键约束修饰的列才是外键列。
-- 目前从表: cart 主表: sys_user
-- 外键约束都在从表里面进行设置。
-- ALTER TABLE cart ADD CONSTRAINT FOREIGN KEY (uid) REFERENCES sys_user (id);
-- ALTER TABLE sys_user ADD CONSTRAINT FOREIGN KEY (cid) REFERENCES cart (id);
CREATE TABLE cart(
id int auto_increment,
total_money DECIMAL(20,3) COMMENT '总金额',
uid BIGINT(10) COMMENT '外键列,数据严格参照用户表的id数据',
PRIMARY KEY(id),
FOREIGN KEY(uid) REFERENCES sys_user(id)
);
CREATE TABLE `cart` (
`id` int NOT NULL AUTO_INCREMENT,
`total_money` decimal(20,3) DEFAULT NULL COMMENT '总金额',
`uid` bigint DEFAULT NULL COMMENT '外键列,数据严格参照用户表的id数据',
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
CONSTRAINT `cart_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `sys_user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- RESTRICT
-- 1.操作主表
SELECT * FROM sys_user; -- ok
INSERT INTO sys_user (true_name) VALUES ('admin'); -- ok
UPDATE sys_user SET age=20 WHERE id=1; -- ok
DELETE FROM sys_user WHERE id=3;
DELETE FROM sys_user WHERE id=1;
-- 删除主表 遍历查询所有子表是否关联使用id的数据
-- 没有使用 可以删除
-- 子表在使用这些数据 无法删除的
-- 保证数据安全性
-- 2.操作子表
SELECT * from cart;
INSERT INTO cart (total_money,uid) VALUES (1000,2);
-- 新增失败 没有参照主表的数据
UPDATE cart SET uid =1001 WHERE id=3;
DELETE FROM cart WHERE id=3; -- ok
-- SET NULL
-- 1.操作主表
SELECT * FROM sys_user; -- ok
INSERT INTO sys_user (true_name) VALUES ('admin'); -- ok
UPDATE sys_user SET age=30 WHERE id=2; -- ok
DELETE FROM sys_user WHERE id=4;
DELETE FROM sys_user WHERE id=1;
-- 删除主表 遍历查询所有子表是否关联使用id的数据
-- 没有使用 可以删除
-- 子表在使用这些数据 会遍历式的先设置子表里面的外键列的数据为null 然后再删除主表的记录
-- 2.操作子表
SELECT * from cart;
INSERT INTO cart (total_money,uid) VALUES (1000,200);
-- 新增失败 没有参照主表的数据
UPDATE cart SET uid =1001 WHERE id=3;
DELETE FROM cart WHERE id=3; -- ok
-- CASCADE(级联)
-- 1.操作主表
SELECT * FROM sys_user; -- ok
INSERT INTO sys_user (true_name) VALUES ('admin'); -- ok
UPDATE sys_user SET age=30 WHERE id=5; -- ok
DELETE FROM sys_user WHERE id=5;
DELETE FROM sys_user WHERE id=2;
-- 删除主表 遍历查询所有子表是否关联使用id的数据
-- 没有使用 可以删除
-- 子表在使用这些数据 会遍历式的删除子表相关记录 然后再删除主表的记录
-- 2.操作子表
SELECT * FROM sys_user;
SELECT * from cart;
INSERT INTO cart (total_money,uid) VALUES (1000,200);
-- 新增失败 没有参照主表的数据
UPDATE cart SET uid =1001 WHERE id=3;
DELETE FROM cart WHERE id=3; -- ok