Mysql数据库 | 第六章 | 表复制和去重 | 合并查询 | 外连接 | 主键 | 外键 | check约束

P 51 表复制和去重 2022/8/1

1.表复制

  • 自我复制数据(蠕虫复制)

有时,为了对某个sql语句进行效率测试,我们需要海量数据时,可以使用此法为表创建海量数据。

代码演示以及相关截图:

sql 复制代码
-- 表的复制
-- 为了对某个sql语句进行效率测试,我们需要海量数据时,可以使用此法为表创建海量数据。
CREATE TABLE my_tab01
	(id INT,
	`name` VARCHAR(32),
	sal DOUBLE,
	job VARCHAR(32),
	deptno INT);
DESC my_tab01;
SELECT * FROM my_tab01;


-- 演示如何自我复制
-- 1.先把emp表的记录复制到my_tab01
INSERT INTO my_tab01
	(id ,`name`,sal,job,deptno)
	SELECT empno,ename,sal,job,deptno FROM emp;
-- 2.自我复制
INSERT INTO my_tab01
	SELECT * FROM my_tab01;

-- ???如何删除掉一张表重复记录
-- 1.先创建一张表 my_tab02,
SELECT * FROM my_tab02;
-- 2.让my_tab02有重复记录
CREATE TABLE my_tab02 LIKE emp;  -- 这个语句 把emp表的结构(列),复制到my_tab02
DESC my_tab02;

INSERT INTO my_tab02
	SELECT * FROM emp;
-- 3.考虑去重
/*
	思路:
	(1)先创建一张临时表my_tmp , 该表的结构和my_tab02 一样
	(2)把my_tab02的记录通过distinct 关键字处理后 把记录复制到my_tmp 
	(3)清除掉my_tab02 记录	
	(4)把my_tmp 表的记录复制到my_tab02
	(5)drop掉临时表my_tmp
*/
-- (1)
CREATE TABLE my_tmp LIKE my_tab02;
DESC my_tmp;
-- (2)  这步其实也可删除my_tab02表,重命名my_tmp表为my_tab02
INSERT INTO my_tmp
	SELECT DISTINCT * FROM my_tab02;
-- (3)
DELETE FROM my_tab02;
-- (4)
INSERT INTO my_tab02
	SELECT * FROM my_tmp;
-- (5)
DROP TABLE my_tmp;
SELECT * FROM my_tab02;

P 52 合并查询 2022/8/1

1.合并查询

代码演示以及相关截图:

sql 复制代码
-- 合并查询
 SELECT ename,sal,job FROM emp WHERE sal>2500;       -- 5条记录
 
 SELECT ename,sal,job FROM emp WHERE job ='MANAGER';  -- 3
 
 -- 1.union all 合并多个select语句的结果,不会去除重复项
 SELECT ename,sal,job FROM emp WHERE sal>2500     
 UNION ALL 
 SELECT ename,sal,job FROM emp WHERE job ='MANAGER'; 
 
 -- 2.union 合并多个select语句的结果,会去除重复项
 SELECT ename,sal,job FROM emp WHERE sal>2500     
 UNION 
 SELECT ename,sal,job FROM emp WHERE job ='MANAGER'; 

P 53 外连接需求 2022/8/1

1.外连接

问题引出:

代码演示以及相关截图:

sql 复制代码
-- 外连接
-- 比如:?列出部门名称和这些部门的员工名称和工作,同时要求,显示哪些没有员工的部门。

-- 使用之前已经学过的多表查询的SQL,看看效果如何?
SELECT emp.deptno,dname,ename,job
	FROM emp,dept
	WHERE dept.deptno = emp.deptno
	ORDER BY dname;     -- 无法显示到没有员工的40部门,?可是需要显示

P 54 左外连右外连 2022/8/1

1.外连接详细

相关语法:

代码演示以及相关截图:

sql 复制代码
 -- 外连接
-- 小提示:但是在实际开发环境中,大多数情况下使用的是前面学过的连接(内连接)。
--  左外连接,右外连接	
-- 创建stu 
SELECT * FROM stu;
CREATE TABLE  stu 
	( id INT ,
	`name` VARCHAR(32));
INSERT INTO stu 
	VALUES(1,'jack'),(2,'tom'),(3,'kity'),(4,'nono');
-- 创建exam 
SELECT * FROM exam;
CREATE TABLE exam(
	id INT,
	grade INT);
INSERT INTO exam
	VALUES(1,56),(2,76),(11,8);

-- 要求:
-- 1.使用左连接(显示所有人的成绩,如果没有成绩,也要显示该人的姓名和ID号,成绩显示为空)
SELECT `name`,stu.id,grade 
	FROM stu,exam
	WHERE stu.id = exam.id  -- 没有显示没有成绩的同学

-- 改成左外连接
SELECT  `name`,stu.id,grade
	FROM stu LEFT JOIN exam
	ON stu.id = exam.id

-- 使用右外连接(显示所有成绩,如果没有名字匹配,显示空)
-- 即:右边的表(exam) 和左边的表(stu)没有匹配的记录,也会把右表的记录显示出来
SELECT `name`,stu.id,grade
	FROM stu RIGHT JOIN exam
	ON stu.id = exam.id
	
-- 题目练习:
-- 列出部门名称和这些部门的员工信息(名字和工作),同时列出那些没有员工的部门名。
-- 使用右外连接
SELECT dname,job,ename,emp.deptno 
	FROM emp RIGHT JOIN dept
	ON dept.deptno = emp.deptno;
-- 使用左外连接
SELECT dname,job,ename,emp.deptno
	FROM dept LEFT JOIN emp
	ON dept.deptno = emp.deptno;

P 55 主键 2022/8/2

1.MySQL约束

基本介绍:约束用于确保数据库的数据满足特定商业规则。在mysql中,约束包括:not null、(唯一)unique,(主键)primary key,(外健)foreign key和(检查)check五种。

案例代码演示以及相关截图:

sql 复制代码
-- 主键的使用
-- 小提示:在实际开发中,每一个表往往都会设计一个主键。

-- id  name  email
CREATE TABLE t17 
	(id INT PRIMARY KEY,   -- 表示id这一列是主键
	`name` VARCHAR(32),
	email VARCHAR(32)); 
	
-- 主键列的值是不可以重复的
INSERT INTO t17 VALUES(1,'jack','jack@souhu.com');
INSERT INTO t17 VALUES(2,'tom','tom@souhu.com');
INSERT INTO t17 VALUES(1,'zjc','zjc@souhu.com');  -- 1不可重复,所以会报错
SELECT * FROM t17;

-- ●主键使用的细节讨论
-- 1.primary key 不能重复而且不能为空 null
INSERT INTO t17 VALUES(NULL,'zjc','zjc@souhu.com'); -- 报错不可以为空

-- 2.一张表最多只能有一个主键,但可以是复合主键(比如这个id+name,两列加起来)
CREATE TABLE t18 
	(id INT PRIMARY KEY,
	`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,'jack','jack@souhu.com');
INSERT INTO t18 VALUES(1,'tom','tom@souhu.com');  -- 可以添加
INSERT INTO t18 VALUES(1,'Jack','xxxx@souhu.com'); -- 不可以添加,违反了复合主键
SELECT * FROM  t18;
-- 3.主键的指定方式有两种
-- ● 直接在字段后指定:字段名 primary key 
-- ● 在表定义最后些 primary key(列名)

-- 4.使用的desc表名,可以看到primary key 的情况
DESC t18;  -- 查看t18表的结果,显示约束情况

P 56 unique 2022/8/2

1.unique ------唯一

代码演示以及相关截图:

sql 复制代码
-- unique 的使用
CREATE TABLE t21 
	( id INT UNIQUE,  -- 表示id列是不可以重复的
	`name` VARCHAR(32),
	email VARCHAR(32));

 INSERT INTO t21 VALUES(1,'jack','jack@souhu.com');
 INSERT INTO t21 VALUES(1,'tom','tom@souhu.com');
 
 SELECT * FROM t21;
 
 -- unique 使用的细节:
 -- 1.如果没有指定not null ,则unique字段可以有多个null
 -- 如果一个列(字段),是unique not null 使用效果类似primary key
 INSERT INTO t21 VALUES(NULL,'tom','tom@souhu.com');
 
 -- 2.一张表中可以有多个unique字段
 CREATE TABLE t22 
	( id INT UNIQUE,  -- 表示id列是不可以重复的
	`name` VARCHAR(32) UNIQUE,
	email VARCHAR(32)) ;
 
 DESC t22;

P 57 外键 2022/8/2

1.外界约束示意图

P 58 外键使用细节2022/8/2

1.foreign key

代码演示以及相关截图:

sql 复制代码
-- 外健演示

-- 创建 主表 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));

-- 测试数据:
SELECT * FROM my_class;

INSERT INTO my_class
	VALUES(100,'java'),(200,'web');
INSERT INTO my_class
	VALUES(300,'php')	

SELECT * FROM my_stu;

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,null不指向任何地方
	
-- 细节:一旦建立主外键的关系,数据不能随意删除了。
-- (取决于外健有没有数据指向他,如需要删除,需要删除所有指向他的数据)

2.foreign key ------细节说明

P 59 ckeck 2022/8/2

1.check简介

代码演示以及相关截图:

sql 复制代码
-- 演示check 的使用
-- mysql 5.7目前还不支持check ,只做语法检验,但不会生效

-- 测试
CREATE TABLE t23 (
	id INT PRIMARY KEY,
	`name` VARCHAR(32),
	sex VARCHAR(6) CHECK (sex IN ('man','woman')),  -- 性别强制为男或者女的
	sal DOUBLE CHECK (sal > 1001 AND sal < 2000));  -- sal大于1001,小于2000
	
-- 添加数据
INSERT INTO t23
	VALUES(1,'jack','mid',1);
SELECT * FROM t23;   -- 查询然而并没有生效,所以在mysql 5.7 还不会生效

P 60 商品表设计 2022/8/3

1.商品表设计要求(约束练习)

代码演示以及相关截图:

sql 复制代码
-- 商品表的设计
-- 使用约束的练习

-- 现有一个商店的数据库shop_db,记录客服及其购物情况,由下面三个表组成:
-- 商品goods (商品号goods_id,商品名goods_name,单价unitprice,商品类别category)
-- 供应商provider
-- 客户customer(购买订单号custmer_id,姓名name,地址address,电邮email,性别sex,身份证card_id);
-- 购买purchase (购买订单号 order_id,客户号customer_id,商品号goods_id,购买数量nums);
-- 建表,在定义中要求声明[进行合理设计]:
-- (1)每个表的主外键;
-- (2)客户的姓名不能为空值;
-- (3)电邮不能重复;
-- (4)客户的性别[男|女] check  枚举
-- (5)单价unitprice 在1.0 - 9999.99之间check

CREATE DATABASE shop_db;

CREATE TABLE goods 
	(goods_id INT PRIMARY KEY,
	goods_name VARCHAR(64) NOT NULL DEFAULT '',
	unitprice DECIMAL(10,2) NOT NULL DEFAULT 0   -- decimal 更加精确
	CHECK (unitprice >=1.0 AND unitprice <=9999.99),
	category INT NOT NULL DEFAULT 0,
	privider VARCHAR(64) NOT NULL DEFAULT '');
	`goods`
 CREATE TABLE customer 
	( customer_id CHAR(8) PRIMARY KEY,  -- 程序员自己决定
	`name` VARCHAR(64) NOT NULL DEFAULT '',
	address VARCHAR(32) NOT NULL DEFAULT '',
	email VARCHAR(32) UNIQUE NOT NULL,
	sex CHAR(8)NOT NULL,  -- 使用枚举类型,是生效的
	card_Id CHAR(18));
	
CREATE TABLE purchase
	( order_id INT UNSIGNED PRIMARY KEY,
	customer_id CHAR(8) NOT NULL DEFAULT '', -- 外健约束在后
	goods_id INT NOT NULL DEFAULT 0,    
	nums INT NOT NULL DEFAULT 0,
	FOREIGN KEY (customer_id) REFERENCES customer(customer_id),
	FOREIGN KEY (goods_id) REFERENCES goods(goods_id));

DESC goods;
DESC customer;
DESC purchase;
相关推荐
师太,答应老衲吧26 分钟前
SQL实战训练之,力扣:2020. 无流量的帐户数(递归)
数据库·sql·leetcode
Yaml41 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
Channing Lewis1 小时前
salesforce case可以新建一个roll up 字段,统计出这个case下的email数量吗
数据库·salesforce
追风林2 小时前
mac 本地docker-mysql主从复制部署
mysql·macos·docker
毕业设计制作和分享3 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
ketil273 小时前
Redis - String 字符串
数据库·redis·缓存
Hsu_kk4 小时前
MySQL 批量删除海量数据的几种方法
数据库·mysql
编程学无止境4 小时前
第02章 MySQL环境搭建
数据库·mysql
knight-n4 小时前
MYSQL库的操作
数据库·mysql
包饭厅咸鱼5 小时前
QML----复制指定下标的ListModel数据
开发语言·数据库