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;