P 51 表复制和去重 2022/8/1
1.表复制
- 自我复制数据(蠕虫复制)
有时,为了对某个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_tab01SELECT * 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_tab02SELECT * 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_tmpSELECT DISTINCT * FROM my_tab02;
-- (3)
DELETE FROM my_tab02;
-- (4)
INSERT INTO my_tab02SELECT * FROM my_tmp;
-- (5)
DROP TABLE my_tmp;
SELECT * FROM my_tab02;
P 52 合并查询 2022/8/1
1.合并查询
代码演示以及相关截图:
-- 合并查询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,看看效果如何?
SELECT emp.deptno,dname,ename,jobFROM emp,deptWHERE dept.deptno = emp.deptnoORDER BY dname; -- 无法显示到没有员工的40部门,?可是需要显示
P 54 左外连右外连 2022/8/1
1.外连接详细
相关语法:
代码演示以及相关截图:
-- 外连接
-- 小提示:但是在实际开发环境中,大多数情况下使用的是前面学过的连接(内连接)。
-- 左外连接,右外连接
-- 创建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 examVALUES(1,56),(2,76),(11,8);-- 要求:
-- 1.使用左连接(显示所有人的成绩,如果没有成绩,也要显示该人的姓名和ID号,成绩显示为空)
SELECT `name`,stu.id,grade FROM stu,examWHERE stu.id = exam.id -- 没有显示没有成绩的同学-- 改成左外连接
SELECT `name`,stu.id,gradeFROM stu LEFT JOIN examON stu.id = exam.id-- 使用右外连接(显示所有成绩,如果没有名字匹配,显示空)
-- 即:右边的表(exam) 和左边的表(stu)没有匹配的记录,也会把右表的记录显示出来
SELECT `name`,stu.id,gradeFROM stu RIGHT JOIN examON stu.id = exam.id-- 题目练习:
-- 列出部门名称和这些部门的员工信息(名字和工作),同时列出那些没有员工的部门名。
-- 使用右外连接
SELECT dname,job,ename,emp.deptno FROM emp RIGHT JOIN deptON dept.deptno = emp.deptno;
-- 使用左外连接
SELECT dname,job,ename,emp.deptnoFROM dept LEFT JOIN empON dept.deptno = emp.deptno;
P 55 主键 2022/8/2
1.MySQL约束
基本介绍:约束用于确保数据库的数据满足特定商业规则。在mysql中,约束包括:not null、(唯一)unique,(主键)primary key,(外健)foreign key和(检查)check五种。
案例代码演示以及相关截图:
-- 主键的使用
-- 小提示:在实际开发中,每一个表往往都会设计一个主键。-- 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 ——唯一
代码演示以及相关截图:
-- 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 keyINSERT 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
代码演示以及相关截图:
-- 外健演示-- 创建 主表 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_classVALUES(100,'java'),(200,'web');
INSERT INTO my_classVALUES(300,'php') SELECT * FROM my_stu;INSERT INTO my_stuVALUES(1,'tom',100);INSERT INTO my_stuVALUES(2,'jack',200);INSERT INTO my_stuVALUES(4,'mary',400); -- 这条语句会失败,因为400班级不存在INSERT INTO my_stuVALUES(5,'king',NULL); -- 可以,外健没有设置not null,null不指向任何地方-- 细节:一旦建立主外键的关系,数据不能随意删除了。
-- (取决于外健有没有数据指向他,如需要删除,需要删除所有指向他的数据)
2.foreign key ——细节说明
P 59 ckeck 2022/8/2
1.check简介
代码演示以及相关截图:
-- 演示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 t23VALUES(1,'jack','mid',1);
SELECT * FROM t23; -- 查询然而并没有生效,所以在mysql 5.7 还不会生效
P 60 商品表设计 2022/8/3
1.商品表设计要求(约束练习)
代码演示以及相关截图:
-- 商品表的设计
-- 使用约束的练习-- 现有一个商店的数据库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之间checkCREATE 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;