一、约束

1.外键约束

  • 外键约束概念
    • 让表和表之间产生关系,从而保证数据的准确性!
  • 建表时添加外键约束

    • 外键约束格式

      1. CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主表主键列名)
    • 创建表添加外键约束 ```mysql — 创建user用户表 CREATE TABLE USER( id INT PRIMARY KEY AUTO_INCREMENT, — id NAME VARCHAR(20) NOT NULL — 姓名 ); — 添加用户数据 INSERT INTO USER VALUES (NULL,’张三’),(NULL,’李四’),(NULL,’王五’);

— 创建orderlist订单表 CREATE TABLE orderlist( id INT PRIMARY KEY AUTO_INCREMENT, — id number VARCHAR(20) NOT NULL, — 订单编号 uid INT, — 订单所属用户 CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id) — 添加外键约束 ); — 添加订单数据 INSERT INTO orderlist VALUES (NULL,’hm001’,1),(NULL,’hm002’,1), (NULL,’hm003’,2),(NULL,’hm004’,2), (NULL,’hm005’,3),(NULL,’hm006’,3);

— 添加一个订单,但是没有所属用户。无法添加 INSERT INTO orderlist VALUES (NULL,’hm007’,8); — 删除王五这个用户,但是订单表中王五还有很多个订单呢。无法删除 DELETE FROM USER WHERE NAME=’王五’;

  1. - 删除外键约束
  2. ```mysql
  3. -- 标准语法
  4. ALTER TABLE 表名 DROP FOREIGN KEY 外键名;
  5. -- 删除外键
  6. ALTER TABLE orderlist DROP FOREIGN KEY ou_fk1;
  • 建表后添加外键约束
  1. -- 标准语法
  2. ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名);
  3. -- 添加外键约束
  4. ALTER TABLE orderlist ADD CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id);

2.外键的级联更新和级联删除(了解)

  • 什么是级联更新和级联删除
    • 当我想把user用户表中的某个用户删掉,我希望该用户所有的订单也随之被删除
    • 当我想把user用户表中的某个用户id修改,我希望订单表中该用户所属的订单用户编号也随之修改
  • 添加级联更新和级联删除
  1. -- 添加外键约束,同时添加级联更新 标准语法
  2. ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名) ON UPDATE CASCADE;
  3. -- 添加外键约束,同时添加级联删除 标准语法
  4. ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名) ON DELETE CASCADE;
  5. -- 添加外键约束,同时添加级联更新和级联删除 标准语法
  6. ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY (本表外键列名) REFERENCES 主表名(主键列名) ON UPDATE CASCADE ON DELETE CASCADE;
  7. -- 删除外键约束
  8. ALTER TABLE orderlist DROP FOREIGN KEY ou_fk1;
  9. -- 添加外键约束,同时添加级联更新和级联删除
  10. ALTER TABLE orderlist ADD CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id) ON UPDATE CASCADE ON DELETE CASCADE;
  11. -- 将王五用户的id修改为5 订单表中的uid也随之被修改
  12. UPDATE USER SET id=5 WHERE id=3;
  13. -- 将王五用户删除 订单表中该用户所有订单也随之删除
  14. DELETE FROM USER WHERE id=5;

补充内容

1_范式概述(理解)

  • 范式就是设计数据库时需要遵循的一些规范.
  • 设计关系型数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范被称为不同的范式,各种范式呈递归规范,越高的范式数据冗余越小.
  • 范式的分类
    • 第一范式(INF)
    • 第二范式(2NF)
    • 第三范式(3NF)
    • 巴斯-科德(BCNF)
    • 第四范式(4NF)
    • 第五范式(5NF[完美范式]
  • 总结
    • 一般数据库的设计负责第三范式即可,数据库符合的范式越高,代表表越多,表越多代表表之间的关系越复杂,虽然符合的范式高,但是不利于SQL语句的书写.
    • 要求越高,表越复杂,表越复杂,查询效率越低。为了提高效率,数据可以存在一定的冗余。

2_三大范式详解(理解)

  • 第一范式(1NF)
    • 第一范式的目标是确保每列的原子性
    • 如果每列都是不可再分的最小数据单元(也称为最小的原子单元),则满足第一范式(1NF)
      2019-09-18_235327.jpg
  • 第二范式(2NF)
    • 如果一个关系满足1NF,并且除了主键以外的其他列,都依赖于该主键,则满足第二范式(2NF)
    • 第二范式要求每个表只描述一件事情,表中的每一列都完全依赖于主键
      2019-09-18_235418.jpg
  • 第三范式(3NF)
    • 如果一个关系满足2NF,并且除了主键以外的其他列都不传递依赖于主键列,则满足第三范式(3NF)
    • 第三范式要求表中各列必须和主键直接相关,不能间接相关
      2019-09-18_235444.jpg

二、多表设计

1.一对一(了解)

  • 分析
    • 人和身份证。一个人只有一个身份证,一个身份证只能对应一个人!
  • 实现原则
    • 在任意一个表建立外键,去关联另外一个表的主键
  • SQL演示
  1. -- 创建db5数据库
  2. CREATE DATABASE db5;
  3. -- 使用db5数据库
  4. USE db5;
  5. -- 创建person
  6. CREATE TABLE person(
  7. id INT PRIMARY KEY AUTO_INCREMENT,
  8. NAME VARCHAR(20)
  9. );
  10. -- 添加数据
  11. INSERT INTO person VALUES (NULL,'张三'),(NULL,'李四');
  12. -- 创建card
  13. CREATE TABLE card(
  14. id INT PRIMARY KEY AUTO_INCREMENT,
  15. number VARCHAR(50),
  16. pid INT UNIQUE,
  17. CONSTRAINT cp_fk1 FOREIGN KEY (pid) REFERENCES person(id) -- 添加外键
  18. );
  19. -- 添加数据
  20. INSERT INTO card VALUES (NULL,'12345',1),(NULL,'56789',2);
  • 图解

01.png

2.一对多

  • 分析
    • 用户和订单。一个用户可以有多个订单!
    • 商品分类和商品。一个分类下可以有多个商品!
  • 实现原则
    • 在多的一方,建立外键约束,来关联一的一方主键
  • SQL演示
  1. /*
  2. 用户和订单
  3. */
  4. -- 创建user
  5. CREATE TABLE USER(
  6. id INT PRIMARY KEY AUTO_INCREMENT,
  7. NAME VARCHAR(20)
  8. );
  9. -- 添加数据
  10. INSERT INTO USER VALUES (NULL,'张三'),(NULL,'李四');
  11. -- 创建orderlist
  12. CREATE TABLE orderlist(
  13. id INT PRIMARY KEY AUTO_INCREMENT,
  14. number VARCHAR(20),
  15. uid INT,
  16. CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id) -- 添加外键约束
  17. );
  18. -- 添加数据
  19. INSERT INTO orderlist VALUES (NULL,'hm001',1),(NULL,'hm002',1),(NULL,'hm003',2),(NULL,'hm004',2);
  20. /*
  21. 商品分类和商品
  22. */
  23. -- 创建category
  24. CREATE TABLE category(
  25. id INT PRIMARY KEY AUTO_INCREMENT,
  26. NAME VARCHAR(10)
  27. );
  28. -- 添加数据
  29. INSERT INTO category VALUES (NULL,'手机数码'),(NULL,'电脑办公');
  30. -- 创建product
  31. CREATE TABLE product(
  32. id INT PRIMARY KEY AUTO_INCREMENT,
  33. NAME VARCHAR(30),
  34. cid INT,
  35. CONSTRAINT pc_fk1 FOREIGN KEY (cid) REFERENCES category(id) -- 添加外键约束
  36. );
  37. -- 添加数据
  38. INSERT INTO product VALUES (NULL,'华为P30',1),(NULL,'小米note3',1),
  39. (NULL,'联想电脑',2),(NULL,'苹果电脑',2);
  • 图解

02.png

3.多对多

  • 分析
    • 学生和课程。一个学生可以选择多个课程,一个课程也可以被多个学生选择!
  • 实现原则
    • 需要借助第三张表中间表,中间表至少包含两个列,这两个列作为中间表的外键,分别关联两张表的主键
  • SQL演示
  1. -- 创建student
  2. CREATE TABLE student(
  3. id INT PRIMARY KEY AUTO_INCREMENT,
  4. NAME VARCHAR(20)
  5. );
  6. -- 添加数据
  7. INSERT INTO student VALUES (NULL,'张三'),(NULL,'李四');
  8. -- 创建course
  9. CREATE TABLE course(
  10. id INT PRIMARY KEY AUTO_INCREMENT,
  11. NAME VARCHAR(10)
  12. );
  13. -- 添加数据
  14. INSERT INTO course VALUES (NULL,'语文'),(NULL,'数学');
  15. -- 创建中间表
  16. CREATE TABLE stu_course(
  17. id INT PRIMARY KEY AUTO_INCREMENT,
  18. sid INT, -- 用于和student表的id进行外键关联
  19. cid INT, -- 用于和course表的id进行外键关联
  20. CONSTRAINT sc_fk1 FOREIGN KEY (sid) REFERENCES student(id), -- 添加外键约束
  21. CONSTRAINT sc_fk2 FOREIGN KEY (cid) REFERENCES course(id) -- 添加外键约束
  22. );
  23. -- 添加数据
  24. INSERT INTO stu_course VALUES (NULL,1,1),(NULL,1,2),(NULL,2,1),(NULL,2,2);
  • 图解

03.png

三、多表查询

1.多表查询-数据准备

  • SQL语句
  1. -- 创建db6数据库
  2. CREATE DATABASE db6;
  3. -- 使用db6数据库
  4. USE db6;
  5. -- 创建user
  6. CREATE TABLE USER(
  7. id INT PRIMARY KEY AUTO_INCREMENT, -- 用户id
  8. NAME VARCHAR(20), -- 用户姓名
  9. age INT -- 用户年龄
  10. );
  11. -- 添加数据
  12. INSERT INTO USER VALUES (1,'张三',23);
  13. INSERT INTO USER VALUES (2,'李四',24);
  14. INSERT INTO USER VALUES (3,'王五',25);
  15. INSERT INTO USER VALUES (4,'赵六',26);
  16. -- 订单表
  17. CREATE TABLE orderlist(
  18. id INT PRIMARY KEY AUTO_INCREMENT, -- 订单id
  19. number VARCHAR(30), -- 订单编号
  20. uid INT, -- 外键字段
  21. CONSTRAINT ou_fk1 FOREIGN KEY (uid) REFERENCES USER(id)
  22. );
  23. -- 添加数据
  24. INSERT INTO orderlist VALUES (1,'hm001',1);
  25. INSERT INTO orderlist VALUES (2,'hm002',1);
  26. INSERT INTO orderlist VALUES (3,'hm003',2);
  27. INSERT INTO orderlist VALUES (4,'hm004',2);
  28. INSERT INTO orderlist VALUES (5,'hm005',3);
  29. INSERT INTO orderlist VALUES (6,'hm006',3);
  30. INSERT INTO orderlist VALUES (7,'hm007',NULL);
  31. -- 商品分类表
  32. CREATE TABLE category(
  33. id INT PRIMARY KEY AUTO_INCREMENT, -- 商品分类id
  34. NAME VARCHAR(10) -- 商品分类名称
  35. );
  36. -- 添加数据
  37. INSERT INTO category VALUES (1,'手机数码');
  38. INSERT INTO category VALUES (2,'电脑办公');
  39. INSERT INTO category VALUES (3,'烟酒茶糖');
  40. INSERT INTO category VALUES (4,'鞋靴箱包');
  41. -- 商品表
  42. CREATE TABLE product(
  43. id INT PRIMARY KEY AUTO_INCREMENT, -- 商品id
  44. NAME VARCHAR(30), -- 商品名称
  45. cid INT, -- 外键字段
  46. CONSTRAINT cp_fk1 FOREIGN KEY (cid) REFERENCES category(id)
  47. );
  48. -- 添加数据
  49. INSERT INTO product VALUES (1,'华为手机',1);
  50. INSERT INTO product VALUES (2,'小米手机',1);
  51. INSERT INTO product VALUES (3,'联想电脑',2);
  52. INSERT INTO product VALUES (4,'苹果电脑',2);
  53. INSERT INTO product VALUES (5,'中华香烟',3);
  54. INSERT INTO product VALUES (6,'玉溪香烟',3);
  55. INSERT INTO product VALUES (7,'计生用品',NULL);
  56. -- 中间表
  57. CREATE TABLE us_pro(
  58. upid INT PRIMARY KEY AUTO_INCREMENT, -- 中间表id
  59. uid INT, -- 外键字段。需要和用户表的主键产生关联
  60. pid INT, -- 外键字段。需要和商品表的主键产生关联
  61. CONSTRAINT up_fk1 FOREIGN KEY (uid) REFERENCES USER(id),
  62. CONSTRAINT up_fk2 FOREIGN KEY (pid) REFERENCES product(id)
  63. );
  64. -- 添加数据
  65. INSERT INTO us_pro VALUES (NULL,1,1);
  66. INSERT INTO us_pro VALUES (NULL,1,2);
  67. INSERT INTO us_pro VALUES (NULL,1,3);
  68. INSERT INTO us_pro VALUES (NULL,1,4);
  69. INSERT INTO us_pro VALUES (NULL,1,5);
  70. INSERT INTO us_pro VALUES (NULL,1,6);
  71. INSERT INTO us_pro VALUES (NULL,1,7);
  72. INSERT INTO us_pro VALUES (NULL,2,1);
  73. INSERT INTO us_pro VALUES (NULL,2,2);
  74. INSERT INTO us_pro VALUES (NULL,2,3);
  75. INSERT INTO us_pro VALUES (NULL,2,4);
  76. INSERT INTO us_pro VALUES (NULL,2,5);
  77. INSERT INTO us_pro VALUES (NULL,2,6);
  78. INSERT INTO us_pro VALUES (NULL,2,7);
  79. INSERT INTO us_pro VALUES (NULL,3,1);
  80. INSERT INTO us_pro VALUES (NULL,3,2);
  81. INSERT INTO us_pro VALUES (NULL,3,3);
  82. INSERT INTO us_pro VALUES (NULL,3,4);
  83. INSERT INTO us_pro VALUES (NULL,3,5);
  84. INSERT INTO us_pro VALUES (NULL,3,6);
  85. INSERT INTO us_pro VALUES (NULL,3,7);
  86. INSERT INTO us_pro VALUES (NULL,4,1);
  87. INSERT INTO us_pro VALUES (NULL,4,2);
  88. INSERT INTO us_pro VALUES (NULL,4,3);
  89. INSERT INTO us_pro VALUES (NULL,4,4);
  90. INSERT INTO us_pro VALUES (NULL,4,5);
  91. INSERT INTO us_pro VALUES (NULL,4,6);
  92. INSERT INTO us_pro VALUES (NULL,4,7);
  • 架构器图解

04.png

2.多表查询-笛卡尔积查询(了解)

  • 有两张表,获取这两个表的所有组合情况
  • 要完成多表查询,需要消除这些没有用的数据
  • 多表查询格式
  1. SELECT
  2. 列名列表
  3. FROM
  4. 表名列表
  5. WHERE
  6. 条件...
  • 笛卡尔积查询
  1. -- 标准语法
  2. SELECT 列名 FROM 表名1,表名2,...;
  3. -- 查询user表和orderlist
  4. SELECT * FROM USER,orderlist;

3.多表查询-内连接查询

  • 查询原理
    • 内连接查询的是两张表有交集的部分数据(有主外键关联的数据)
  • 显式内连接
  1. -- 标准语法
  2. SELECT 列名 FROM 表名1 [INNER] JOIN 表名2 ON 条件;
  3. -- 查询用户信息和对应的订单信息
  4. SELECT * FROM USER INNER JOIN orderlist ON user.id=orderlist.uid;
  5. SELECT * FROM USER JOIN orderlist ON user.id=orderlist.uid;
  6. -- 查询用户信息和对应的订单信息,起别名
  7. SELECT * FROM USER u JOIN orderlist o ON u.id=o.uid;
  8. -- 查询用户姓名,年龄。和订单编号
  9. SELECT
  10. u.`name`, -- 姓名
  11. u.`age`, -- 年龄
  12. o.`number` -- 订单编号
  13. FROM
  14. USER u -- 用户表
  15. INNER JOIN
  16. orderlist o -- 订单表
  17. ON
  18. u.`id` = o.`uid`;
  • 隐式内连接
  1. -- 标准语法
  2. SELECT 列名 FROM 表名1,表名2 WHERE 条件;
  3. -- 查询用户姓名,年龄。和订单编号
  4. SELECT
  5. u.`name`, -- 姓名
  6. u.`age`, -- 年龄
  7. o.`number` -- 订单编号
  8. FROM
  9. USER u, -- 用户表
  10. orderlist o -- 订单表
  11. WHERE
  12. u.`id`=o.`uid`;

4.多表查询-外连接查询

  • 左外连接
    • 查询原理
      • 查询左表的全部数据,和左右两张表有交集部分的数据
    • 基本演示 ```plsql — 标准语法 SELECT 列名 FROM 表名1 LEFT [OUTER] JOIN 表名2 ON 条件;

— 查询所有用户信息,以及用户对应的订单信息 SELECT u.name, — 姓名 u.age, — 年龄 o.number — 订单编号 FROM USER u — 用户表 LEFT OUTER JOIN orderlist o — 订单表 ON u.id=o.uid;

  1. - 右外连接
  2. - 查询原理
  3. - 查询右表的全部数据,和左右两张表有交集部分的数据
  4. - 基本演示
  5. ```plsql
  6. -- 基本语法
  7. SELECT 列名 FROM 表名1 RIGHT [OUTER] JOIN 表名2 ON 条件;
  8. -- 查询所有订单信息,以及订单所属的用户信息
  9. SELECT
  10. u.`name`, -- 姓名
  11. u.`age`, -- 年龄
  12. o.`number` -- 订单编号
  13. FROM
  14. USER u -- 用户表
  15. RIGHT OUTER JOIN
  16. orderlist o -- 订单表
  17. ON
  18. u.`id`=o.`uid`;

5.多表查询-子查询

  • 子查询介绍
    • 查询语句中嵌套了查询语句。我们就将嵌套查询称为子查询!
  • 子查询-结果是单行单列的
    • 可以作为条件,使用运算符进行判断!
    • 基本演示 ```plsql — 标准语法 SELECT 列名 FROM 表名 WHERE 列名=(SELECT 聚合函数(列名) FROM 表名 [WHERE 条件]);

— 查询年龄最高的用户姓名 SELECT MAX(age) FROM USER; — 查询出最高年龄 SELECT NAME,age FROM USER WHERE age=26; — 根据查询出来的最高年龄,查询姓名和年龄 SELECT NAME,age FROM USER WHERE age = (SELECT MAX(age) FROM USER);

  1. - 子查询-结果是多行单列的
  2. - 可以作为条件,使用运算符innot in进行判断!
  3. - 基本演示
  4. ```plsql
  5. -- 标准语法
  6. SELECT 列名 FROM 表名 WHERE 列名 [NOT] IN (SELECT 列名 FROM 表名 [WHERE 条件]);
  7. -- 查询张三和李四的订单信息
  8. SELECT id FROM USER WHERE NAME='张三' OR NAME='李四'; -- 查询张三和李四用户的id
  9. SELECT number,uid FROM orderlist WHERE uid=1 OR uid=2; -- 根据id查询订单
  10. SELECT number,uid FROM orderlist WHERE uid IN (SELECT id FROM USER WHERE NAME='张三' OR NAME='李四');
  • 子查询-结果是多行多列的
    • 可以作为一张虚拟表参与查询!
    • 基本演示 ```plsql — 标准语法 SELECT 列名 FROM 表名 [别名],(SELECT 列名 FROM 表名 [WHERE 条件]) [别名] [WHERE 条件];

— 查询订单表中id大于4的订单信息和所属用户信息 SELECT FROM USER u,(SELECT FROM orderlist WHERE id>4) o WHERE u.id=o.uid;

  1. <a name="19b34773"></a>
  2. #### 6.多表查询-自关联查询
  3. - 自关联查询介绍
  4. - 同一张表中有数据关联。可以多次查询这同一个表!
  5. - 自关联查询演示
  6. ```plsql
  7. -- 创建员工表
  8. CREATE TABLE employee(
  9. id INT PRIMARY KEY AUTO_INCREMENT,
  10. NAME VARCHAR(20),
  11. mgr INT,
  12. salary DOUBLE
  13. );
  14. -- 添加数据
  15. INSERT INTO employee VALUES (1001,'孙悟空',1005,9000.00),
  16. (1002,'猪八戒',1005,8000.00),
  17. (1003,'沙和尚',1005,8500.00),
  18. (1004,'小白龙',1005,7900.00),
  19. (1005,'唐僧',NULL,15000.00),
  20. (1006,'武松',1009,7600.00),
  21. (1007,'李逵',1009,7400.00),
  22. (1008,'林冲',1009,8100.00),
  23. (1009,'宋江',NULL,16000.00);
  24. -- 查询所有员工的姓名及其直接上级的姓名,没有上级的员工也需要查询
  25. /*
  26. 分析:
  27. 员工姓名 employee表 直接上级姓名 employee表
  28. 条件:employee.mgr = employee.id
  29. 查询左表的全部数据,和左右两张表交集部分数据,使用左外连接
  30. */
  31. SELECT
  32. t1.name, -- 员工姓名
  33. t1.mgr, -- 上级编号
  34. t2.id, -- 员工编号
  35. t2.name -- 员工姓名
  36. FROM
  37. employee t1 -- 员工表
  38. LEFT OUTER JOIN
  39. employee t2 -- 员工表
  40. ON
  41. t1.mgr = t2.id;

7.多表查询练习

  • 查询用户的编号、姓名、年龄。订单编号
  1. /*
  2. 分析:
  3. 用户的编号、姓名、年龄 user表 订单编号 orderlist表
  4. 条件:user.id = orderlist.uid
  5. */
  6. SELECT
  7. t1.`id`, -- 用户编号
  8. t1.`name`, -- 用户姓名
  9. t1.`age`, -- 用户年龄
  10. t2.`number` -- 订单编号
  11. FROM
  12. USER t1, -- 用户表
  13. orderlist t2 -- 订单表
  14. WHERE
  15. t1.`id` = t2.`uid`;
  • 查询所有的用户。用户的编号、姓名、年龄。订单编号
  1. /*
  2. 分析:
  3. 用户的编号、姓名、年龄 user表 订单编号 orderlist表
  4. 条件:user.id = orderlist.uid
  5. 查询所有用户,使用左外连接
  6. */
  7. SELECT
  8. t1.`id`, -- 用户编号
  9. t1.`name`, -- 用户姓名
  10. t1.`age`, -- 用户年龄
  11. t2.`number` -- 订单编号
  12. FROM
  13. USER t1 -- 用户表
  14. LEFT OUTER JOIN
  15. orderlist t2 -- 订单表
  16. ON
  17. t1.`id` = t2.`uid`;
  • 查询所有的订单。用户的编号、姓名、年龄。订单编号
  1. /*
  2. 分析:
  3. 用户的编号、姓名、年龄 user表 订单编号 orderlist表
  4. 条件:user.id = orderlist.uid
  5. 查询所有订单,使用右外连接
  6. */
  7. SELECT
  8. t1.`id`, -- 用户编号
  9. t1.`name`, -- 用户姓名
  10. t1.`age`, -- 用户年龄
  11. t2.`number` -- 订单编号
  12. FROM
  13. USER t1 -- 用户表
  14. RIGHT OUTER JOIN
  15. orderlist t2 -- 订单表
  16. ON
  17. t1.`id` = t2.`uid`;
  • 查询用户年龄大于23岁的信息。显示用户的编号、姓名、年龄。订单编号
  1. /*
  2. 分析:
  3. 用户的编号、姓名、年龄 user表 订单编号 orderlist表
  4. 条件:user.age > 23 AND user.id = orderlist.uid
  5. */
  6. /*
  7. select
  8. t1.`id`, -- 用户编号
  9. t1.`name`, -- 用户姓名
  10. t1.`age`, -- 用户年龄
  11. t2.`number` -- 订单编号
  12. from
  13. user t1, -- 用户表
  14. orderlist t2 -- 订单表
  15. where
  16. t1.`age` > 23
  17. and
  18. t1.`id` = t2.`uid`;
  19. */
  20. SELECT
  21. t1.`id`, -- 用户编号
  22. t1.`name`, -- 用户姓名
  23. t1.`age`, -- 用户年龄
  24. t2.`number` -- 订单编号
  25. FROM
  26. USER t1 -- 用户表
  27. LEFT OUTER JOIN
  28. orderlist t2 -- 订单表
  29. ON
  30. t1.`id` = t2.`uid`
  31. WHERE
  32. t1.`age` > 23;
  • 查询张三和李四用户的信息。显示用户的编号、姓名、年龄。订单编号
  1. /*
  2. 分析:
  3. 用户的编号、姓名、年龄 user表 订单编号 orderlist表
  4. 条件:user.id = orderlist.uid AND user.name IN ('张三','李四');
  5. */
  6. SELECT
  7. t1.`id`, -- 用户编号
  8. t1.`name`, -- 用户姓名
  9. t1.`age`, -- 用户年龄
  10. t2.`number` -- 订单编号
  11. FROM
  12. USER t1, -- 用户表
  13. orderlist t2 -- 订单表
  14. WHERE
  15. t1.`id` = t2.`uid`
  16. AND
  17. -- (t1.`name` = '张三' OR t1.`name` = '李四');
  18. t1.`name` IN ('张三','李四');
  • 查询商品分类的编号、分类名称。分类下的商品名称
  1. /*
  2. 分析:
  3. 商品分类的编号、分类名称 category表 分类下的商品名称 product表
  4. 条件:category.id = product.cid
  5. */
  6. SELECT
  7. t1.`id`, -- 分类编号
  8. t1.`name`, -- 分类名称
  9. t2.`name` -- 商品名称
  10. FROM
  11. category t1, -- 商品分类表
  12. product t2 -- 商品表
  13. WHERE
  14. t1.`id` = t2.`cid`;
  • 查询所有的商品分类。商品分类的编号、分类名称。分类下的商品名称
  1. /*
  2. 分析:
  3. 商品分类的编号、分类名称 category表 分类下的商品名称 product表
  4. 条件:category.id = product.cid
  5. 查询所有的商品分类,使用左外连接
  6. */
  7. SELECT
  8. t1.`id`, -- 分类编号
  9. t1.`name`, -- 分类名称
  10. t2.`name` -- 商品名称
  11. FROM
  12. category t1 -- 商品分类表
  13. LEFT OUTER JOIN
  14. product t2 -- 商品表
  15. ON
  16. t1.`id` = t2.`cid`;
  • 查询所有的商品信息。商品分类的编号、分类名称。分类下的商品名称
  1. /*
  2. 分析:
  3. 商品分类的编号、分类名称 category表 分类下的商品名称 product表
  4. 条件:category.id = product.cid
  5. 查询所有的商品信息,使用右外连接
  6. */
  7. SELECT
  8. t1.`id`, -- 分类编号
  9. t1.`name`, -- 分类名称
  10. t2.`name` -- 商品名称
  11. FROM
  12. category t1 -- 商品分类表
  13. RIGHT OUTER JOIN
  14. product t2 -- 商品表
  15. ON
  16. t1.`id` = t2.`cid`;
  • 查询所有的用户和所有的商品。显示用户的编号、姓名、年龄。商品名称
  1. /*
  2. 分析:
  3. 用户的编号、姓名、年龄 user表 商品名称 product表 中间表 us_pro
  4. 条件:us_pro.uid = user.id AND us_pro.pid = product.id
  5. */
  6. SELECT
  7. t1.`id`, -- 用户编号
  8. t1.`name`, -- 用户名称
  9. t1.`age`, -- 用户年龄
  10. t2.`name` -- 商品名称
  11. FROM
  12. USER t1, -- 用户表
  13. product t2, -- 商品表
  14. us_pro t3 -- 中间表
  15. WHERE
  16. t3.`uid` = t1.`id`
  17. AND
  18. t3.`pid` = t2.`id`;
  • 查询张三和李四这两个用户可以看到的商品。显示用户的编号、姓名、年龄。商品名称
  1. /*
  2. 分析:
  3. 用户的编号、姓名、年龄 user表 商品名称 product表 中间表 us_pro
  4. 条件:us_pro.uid = user.id AND us_pro.pid = product.id AND user.name IN ('张三','李四')
  5. */
  6. SELECT
  7. t1.`id`, -- 用户编号
  8. t1.`name`, -- 用户名称
  9. t1.`age`, -- 用户年龄
  10. t2.`name` -- 商品名称
  11. FROM
  12. USER t1, -- 用户表
  13. product t2, -- 商品表
  14. us_pro t3 -- 中间表
  15. WHERE
  16. (t3.`uid` = t1.`id` AND t3.`pid` = t2.`id`)
  17. AND
  18. -- (t1.`name` = '张三' or t1.`name` = '李四');
  19. t1.`name` IN ('张三','李四');

四、视图

1.视图的概念

  • 视图是一种虚拟存在的数据表
  • 这个虚拟的表并不在数据库中实际存在
  • 作用是将一些比较复杂的查询语句的结果,封装到一个虚拟表中。后期再有相同复杂查询时,直接查询这张虚拟表即可

2.视图的好处

  • 简单
    • 对于使用视图的用户不需要关心表的结构、关联条件和筛选条件。因为这张虚拟表中保存的就是已经过滤好条件的结果集
  • 安全
    • 视图可以设置权限 , 致使访问视图的用户只能访问他们被允许查询的结果集
  • 数据独立
    • 一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响

3.视图数据准备

  1. -- 创建db7数据库
  2. CREATE DATABASE db7;
  3. -- 使用db7数据库
  4. USE db7;
  5. -- 创建country
  6. CREATE TABLE country(
  7. id INT PRIMARY KEY AUTO_INCREMENT,
  8. country_name VARCHAR(30)
  9. );
  10. -- 添加数据
  11. INSERT INTO country VALUES (NULL,'中国'),(NULL,'美国'),(NULL,'俄罗斯');
  12. -- 创建city
  13. CREATE TABLE city(
  14. id INT PRIMARY KEY AUTO_INCREMENT,
  15. city_name VARCHAR(30),
  16. cid INT, -- 外键列。关联country表的主键列id
  17. CONSTRAINT cc_fk1 FOREIGN KEY (cid) REFERENCES country(id)
  18. );
  19. -- 添加数据
  20. INSERT INTO city VALUES (NULL,'北京',1),(NULL,'上海',1),(NULL,'纽约',2),(NULL,'莫斯科',3);

4.视图的创建

  • 创建视图语法
  1. -- 标准语法
  2. CREATE VIEW 视图名称 [(列名列表)] AS 查询语句;
  • 普通多表查询,查询城市和所属国家
  1. -- 普通多表查询,查询城市和所属国家
  2. SELECT
  3. t1.*,
  4. t2.country_name
  5. FROM
  6. city t1,
  7. country t2
  8. WHERE
  9. t1.cid = t2.id;
  10. -- 经常需要查询这样的数据,就可以创建一个视图
  • 创建视图基本演示
  1. -- 创建一个视图。将查询出来的结果保存到这张虚拟表中
  2. CREATE
  3. VIEW
  4. city_country
  5. AS
  6. SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;
  • 创建视图并指定列名基本演示
  1. -- 创建一个视图,指定列名。将查询出来的结果保存到这张虚拟表中
  2. CREATE
  3. VIEW
  4. city_country2 (city_id,city_name,cid,country_name)
  5. AS
  6. SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;

5.视图的查询

  • 查询视图语法
  1. -- 标准语法
  2. SELECT * FROM 视图名称;
  • 查询视图基本演示
  1. -- 查询视图。查询这张虚拟表,就等效于查询城市和所属国家
  2. SELECT * FROM city_country;
  3. -- 查询指定列名的视图
  4. SELECT * FROM city_country2;
  5. -- 查询所有数据表,视图也会查询出来
  6. SHOW TABLES;
  • 查询视图创建语法
  1. -- 标准语法
  2. SHOW CREATE VIEW 视图名称;
  • 查询视图创建语句基本演示
  1. SHOW CREATE VIEW city_country;

6.视图的修改

  • 修改视图表中的数据
  1. -- 标准语法
  2. UPDATE 视图名称 SET 列名=值 WHERE 条件;
  3. -- 修改视图表中的城市名称北京为北京市
  4. UPDATE city_country SET city_name='北京市' WHERE city_name='北京';
  5. -- 查询视图
  6. SELECT * FROM city_country;
  7. -- 查询city表,北京也修改为了北京市
  8. SELECT * FROM city;
  9. -- 注意:视图表数据修改,会自动修改源表中的数据
  • 注意:视图表数据修改,会自动修改源表中的数据
  • 修改视图表结构
  1. -- 标准语法
  2. ALTER VIEW 视图名称 [(列名列表)] AS 查询语句;
  3. -- 查询视图2
  4. SELECT * FROM city_country2;
  5. -- 修改视图2的列名city_idid
  6. ALTER
  7. VIEW
  8. city_country2 (id,city_name,cid,country_name)
  9. AS
  10. SELECT t1.*,t2.country_name FROM city t1,country t2 WHERE t1.cid=t2.id;

7.视图的删除

  • 删除视图
  1. -- 标准语法
  2. DROP VIEW [IF EXISTS] 视图名称;
  3. -- 删除视图
  4. DROP VIEW city_country;
  5. -- 删除视图2,如果存在则删除
  6. DROP VIEW IF EXISTS city_country2;

8.视图的总结

  • 视图是一种虚拟存在的数据表
  • 这个虚拟的表并不在数据库中实际存在
  • 视图就是将一条SELECT查询语句的结果封装到了一个虚拟表中,所以我们在创建视图的时候,工作重心就要放在这条SELECT查询语句上
  • 视图的好处
    • 简单
    • 安全
    • 数据独立

五、备份与还原

1.命令行方式

  • 备份
    • 使用SecureCRT工具连接到Linux系统,输入:mysqldump -u root -p 数据库名称 > 文件保存路径

12.png

  • 进入文件保存路径,查看文件是否存在 cd /root/mysql

14.png

  • 恢复
    • 登录mysql数据库

15.png

  • 删除已经备份的数据库

16.png

  • 重新创建名称相同的数据库

17.png

  • 使用该数据库

18.png

  • 导入文件执行:source 备份文件路径;

19.png

2.图形化界面方式

  • 备份

05.png
06.png

07.png

  • 恢复

08.png

09.png

10.png

11.png