MySQL--五大约束详解

发布时间:2024年01月24日

``# 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 外键约束(维护多表关系的)    

1 NOT NULL

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
);

2 UNIQUE

唯一性约束/索引(是数据结构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;

在这里插入图片描述

在这里插入图片描述

3 DEFAULT

给列设置默认值。

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;

在这里插入图片描述

4 PRIMARY KEY

既可以是行级约束,又可以是表级约束。自带索引的。

1. 一张表里面只能使用1PRIMARY KEY
2. 使用 PRIMARY KEY 修饰的列  一般称为 "主键列"
3. 主键列的数据: 非空+唯一
4. 理论上任意一个列都可以作为主键列。实际开发中,一般都是id。  int  bigint 
5. 为什么要使用主键约束?
   1. 保证记录唯一性。
   2. 满足表设计的3大范式。
      2.1 第一范式: 保证列的原子性 列不可再分的原则。
          收货地址:  address 河南省郑州市高新区  
          这个地址可以再分的  provice  city  area 
      2.2 第二范式: 在满足第一范式前提下,保证行记录的唯一性。 建议使用主键列。
      2.33范式: 在满足第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;

5 FOREIGN KEY

外键约束,自带索引。

维护多张表的关系。

虽然我们讲解了 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
文章来源:https://blog.csdn.net/qq_57547315/article/details/135706699
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。