├── README.md
├── SQL基础教程.pdf
├── Task00:绪论 - 环境搭建.md
├── Task01:初识数据库.md
├── Task02:基础查询与排序.md
├── Task03:复杂一点的查询.md
├── Task04:集合运算.md
├── Task05:SQL高级处理.md
├── Task06:综合练习.md
├── img
├── .gitkeep
├── 00 SQL基础课程.png
├── ch00
│ ├── .gitkeep
│ ├── ch0001.png
│ ├── ch0002.png
│ ├── ch0003.png
│ ├── ch0004.png
│ ├── ch0005.png
│ ├── ch0006.png
│ ├── ch0007.png
│ ├── ch0008.png
│ ├── ch0009.png
│ ├── ch0010.png
│ ├── ch0011.png
│ ├── ch0012.png
│ ├── ch0013.png
│ ├── ch0014.png
│ ├── ch0015.png
│ ├── ch0016.png
│ ├── ch0017.png
│ ├── ch0018.png
│ ├── ch0019.png
│ ├── ch0020.png
│ ├── ch0021.png
│ ├── ch0022.png
│ ├── ch0023.png
│ ├── ch0024.png
│ ├── ch0025.png
│ ├── ch0026.png
│ ├── ch0027.png
│ ├── ch0028.png
│ ├── ch0029.png
│ ├── ch0030.png
│ ├── ch0031.png
│ ├── ch0032.png
│ ├── ch0033.png
│ ├── ch0034.png
│ ├── ch0035.png
│ ├── ch0036.png
│ ├── ch0037.png
│ ├── ch0038.png
│ ├── ch0039.png
│ ├── ch0040.png
│ ├── ch0041.png
│ ├── ch0042.png
│ ├── ch0043.png
│ ├── ch0044.png
│ ├── ch0045.png
│ ├── ch0046.png
│ ├── ch0047.png
│ ├── ch0048.png
│ ├── ch0049.png
│ ├── ch0050.png
│ ├── ch0051.png
│ ├── ch0052.png
│ ├── ch0053.png
│ ├── ch0054.png
│ ├── ch00541.png
│ ├── ch0055.png
│ ├── ch0056.png
│ ├── ch0057.png
│ ├── ch0058.png
│ ├── ch0059.png
│ ├── ch0060.png
│ ├── ch0061.png
│ ├── ch0062.png
│ ├── ch0063.png
│ ├── ch0064.png
│ ├── ch0065.png
│ ├── ch0066.png
│ ├── ch0067.png
│ ├── ch0068.png
│ ├── ch0069.png
│ ├── ch0070.png
│ ├── ch0071.png
│ ├── ch0072.png
│ ├── ch0073.png
│ ├── ch0074.png
│ └── ch0075.png
├── ch01
│ ├── .gitkeep
│ ├── ch01.01系统结构.jpg
│ ├── ch01.02表的示例.jpg
│ ├── ch01.03商品表和列名对应关系.png
│ └── ch01.04习题1.png
├── ch02
│ ├── .gitkeep
│ ├── ch02.01and.png
│ ├── ch02.02or.png
│ ├── ch02.03true.png
│ ├── ch02.04true2.png
│ ├── ch02.05true3.png
│ ├── ch02.06cut.png
│ ├── ch02.07groupby.png
│ ├── ch02.08test26.png
│ └── ch02.09test27.png
├── ch03
│ ├── .gitkeep
│ ├── ch03.01view.png
│ ├── ch03.02view2.png
│ ├── ch03.03view3.png
│ ├── ch03.04view4.png
│ ├── ch03.05result.png
│ ├── ch03.06productsum.png
│ ├── ch03.07productsum2.png
│ ├── ch03.08productsumsrc.png
│ ├── ch03.09case.png
│ ├── ch03.10function.png
│ ├── ch03.11casewhen1.png
│ └── ch03.12casewhen2.png
├── ch04
│ ├── .gitkeep
│ ├── ch04.01.png
│ ├── ch04.02.png
│ ├── ch04.03union.png
│ ├── ch04.04result.png
│ ├── ch04.05result2.png
│ ├── ch04.06result3.png
│ ├── ch04.07result4.png
│ ├── ch04.08result5.png
│ ├── ch04.09except.png
│ ├── ch04.10.png
│ ├── ch04.11.png
│ ├── ch04.12.png
│ ├── ch04.13join.png
│ ├── ch04.14tb.png
│ ├── ch04.15shopproduct.png
│ ├── ch04.16tb73.png
│ ├── ch04.17result.png
│ ├── ch04.18result2.png
│ ├── ch04.19result3.png
│ ├── ch04.20.png
│ ├── ch04.21.png
│ ├── ch04.22.png
│ ├── ch04.23.png
│ ├── ch04.24.png
│ ├── ch04.25.png
│ ├── ch04.26.png
│ ├── ch04.27.png
│ ├── ch04.28.png
│ ├── ch04.29.png
│ ├── ch04.30.png
│ ├── ch04.31.png
│ ├── ch04.32.png
│ ├── ch04.33.png
│ ├── ch04.34.png
│ ├── ch04.35.png
│ ├── ch04.36.png
│ └── ch04.37.png
├── ch05
│ ├── .gitkeep
│ ├── ch0501.png
│ ├── ch0502.png
│ ├── ch0503.png
│ ├── ch0504.png
│ ├── ch0505.png
│ ├── ch0506.png
│ ├── ch0507.png
│ ├── ch0508.png
│ ├── ch0509.png
│ └── ch0510.png
└── datawhale_code.jpeg
└── shop.sql
/README.md:
--------------------------------------------------------------------------------
1 | # SQL基础教程学习笔记(team-learning-sql)
2 |
3 | # 最新项目地址为 [https://github.com/datawhalechina/wonderful-sql](https://github.com/datawhalechina/wonderful-sql)
4 |
5 | SQL 在诸多工作中应用广泛,数据分析、开发、测试、维护、产品经理都有可能会用到SQL,而在大学里曾经系统学习SQL的人比较少,
6 | 这就要求我们在工作中来学习SQL。然而,自己学习很容易走弯路。笔者通过近几年的摸索学习,发现了一本很好的教材[《SQL基础教程 第2版》](https://book.douban.com/subject/27055712/)作者:MICK,
7 | 我如获至宝,心想这么好的教材应该让更多的人了解到,以便小伙伴们少走弯路,于是乎,我就联合DataWhale团队成员编写了这一版学习笔记。希望可以帮你更好的学习SQL。
8 |
9 | ## 使用方法
10 |
11 | 考虑到易用性和普及度,课程内容采用`MySql`进行介绍,对教材内容进行了整合,具体的目录参见下方,每个章节附带了练习题,最后一个章节是
12 | leetcode练习题和大厂面试题,顺利完成本课程学习后,应付初级SQL面试不在话下,还等什么呢?现在就开始吧~~
13 |
14 | ## 目录
15 |
16 | * Task00:绪论 - 环境搭建
17 | - [x] [1. MySQL 8.0 的安装](https://github.com/datawhalechina/team-learning-sql/blob/main/Task00%EF%BC%9A%E7%BB%AA%E8%AE%BA%20-%20%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md#1-mysql-80-%E7%9A%84%E5%AE%89%E8%A3%85)
18 | - [x] [2. 连接 MySQL 并执行 SQL 查询](https://github.com/datawhalechina/team-learning-sql/blob/main/Task00%EF%BC%9A%E7%BB%AA%E8%AE%BA%20-%20%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md#2-%E8%BF%9E%E6%8E%A5-mysql-%E5%B9%B6%E6%89%A7%E8%A1%8C-sql-%E6%9F%A5%E8%AF%A2)
19 |
20 | * Task01:初识数据库
21 | - [x] [1.1 初识数据库](https://github.com/datawhalechina/team-learning-sql/blob/main/Task01%EF%BC%9A%E5%88%9D%E8%AF%86%E6%95%B0%E6%8D%AE%E5%BA%93.md#11-%E5%88%9D%E8%AF%86%E6%95%B0%E6%8D%AE%E5%BA%93)
22 | - [x] [1.2 初识SQL](https://github.com/datawhalechina/team-learning-sql/blob/main/Task01%EF%BC%9A%E5%88%9D%E8%AF%86%E6%95%B0%E6%8D%AE%E5%BA%93.md#11-%E5%88%9D%E8%AF%86%E6%95%B0%E6%8D%AE%E5%BA%93)
23 |
24 | * Task02:基础查询与排序
25 | - [x] [2.1 SELECT语句基础](https://github.com/datawhalechina/team-learning-sql/blob/main/Task02%EF%BC%9A%E5%9F%BA%E7%A1%80%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%BA%8F.md#21-select%E8%AF%AD%E5%8F%A5%E5%9F%BA%E7%A1%80)
26 | - [x] [2.2 算术运算符和比较运算符](https://github.com/datawhalechina/team-learning-sql/blob/main/Task02%EF%BC%9A%E5%9F%BA%E7%A1%80%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%BA%8F.md#22-%E7%AE%97%E6%9C%AF%E8%BF%90%E7%AE%97%E7%AC%A6%E5%92%8C%E6%AF%94%E8%BE%83%E8%BF%90%E7%AE%97%E7%AC%A6)
27 | - [x] [2.3 逻辑运算符](https://github.com/datawhalechina/team-learning-sql/blob/main/Task02%EF%BC%9A%E5%9F%BA%E7%A1%80%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%BA%8F.md#23-%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97%E7%AC%A6)
28 | - [x] [2.4 对表进行聚合查询](https://github.com/datawhalechina/team-learning-sql/blob/main/Task02%EF%BC%9A%E5%9F%BA%E7%A1%80%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%BA%8F.md#24-%E5%AF%B9%E8%A1%A8%E8%BF%9B%E8%A1%8C%E8%81%9A%E5%90%88%E6%9F%A5%E8%AF%A2)
29 | - [x] [2.5 对表进行分组](https://github.com/datawhalechina/team-learning-sql/blob/main/Task02%EF%BC%9A%E5%9F%BA%E7%A1%80%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%BA%8F.md#25-%E5%AF%B9%E8%A1%A8%E8%BF%9B%E8%A1%8C%E5%88%86%E7%BB%84)
30 | - [x] [2.6 为聚合结果指定条件](https://github.com/datawhalechina/team-learning-sql/blob/main/Task02%EF%BC%9A%E5%9F%BA%E7%A1%80%E6%9F%A5%E8%AF%A2%E4%B8%8E%E6%8E%92%E5%BA%8F.md#26-%E4%B8%BA%E8%81%9A%E5%90%88%E7%BB%93%E6%9E%9C%E6%8C%87%E5%AE%9A%E6%9D%A1%E4%BB%B6)
31 |
32 | * Task03:复杂一点的查询
33 | - [x] [3.1 视图](https://github.com/datawhalechina/team-learning-sql/blob/main/Task03%EF%BC%9A%E5%A4%8D%E6%9D%82%E4%B8%80%E7%82%B9%E7%9A%84%E6%9F%A5%E8%AF%A2.md#31-%E8%A7%86%E5%9B%BE)
34 | - [x] [3.2 子查询](https://github.com/datawhalechina/team-learning-sql/blob/main/Task03%EF%BC%9A%E5%A4%8D%E6%9D%82%E4%B8%80%E7%82%B9%E7%9A%84%E6%9F%A5%E8%AF%A2.md#33-%E5%90%84%E7%A7%8D%E5%90%84%E6%A0%B7%E7%9A%84%E5%87%BD%E6%95%B0)
35 | - [x] [3.3 各种各样的函数](https://github.com/datawhalechina/team-learning-sql/blob/main/Task03%EF%BC%9A%E5%A4%8D%E6%9D%82%E4%B8%80%E7%82%B9%E7%9A%84%E6%9F%A5%E8%AF%A2.md#33-%E5%90%84%E7%A7%8D%E5%90%84%E6%A0%B7%E7%9A%84%E5%87%BD%E6%95%B0)
36 | - [x] [3.4 谓词](https://github.com/datawhalechina/team-learning-sql/blob/main/Task03%EF%BC%9A%E5%A4%8D%E6%9D%82%E4%B8%80%E7%82%B9%E7%9A%84%E6%9F%A5%E8%AF%A2.md#34-%E8%B0%93%E8%AF%8D)
37 | - [x] [3.5 CASE 表达式](https://github.com/datawhalechina/team-learning-sql/blob/main/Task03%EF%BC%9A%E5%A4%8D%E6%9D%82%E4%B8%80%E7%82%B9%E7%9A%84%E6%9F%A5%E8%AF%A2.md#35-case-%E8%A1%A8%E8%BE%BE%E5%BC%8F)
38 |
39 | * Task04:集合运算
40 | - [x] [4.1 表的加减法](https://github.com/datawhalechina/team-learning-sql/blob/main/Task04%EF%BC%9A%E9%9B%86%E5%90%88%E8%BF%90%E7%AE%97.md#41-%E8%A1%A8%E7%9A%84%E5%8A%A0%E5%87%8F%E6%B3%95)
41 | - [x] [4.2 连结(JOIN)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task04%EF%BC%9A%E9%9B%86%E5%90%88%E8%BF%90%E7%AE%97.md#42-%E8%BF%9E%E7%BB%93join)
42 |
43 | * Task05:SQL高级处理
44 | - [x] [5.1 窗口函数](https://github.com/datawhalechina/team-learning-sql/blob/main/Task05%EF%BC%9ASQL%E9%AB%98%E7%BA%A7%E5%A4%84%E7%90%86.md#51-%E7%AA%97%E5%8F%A3%E5%87%BD%E6%95%B0)
45 | - [x] [5.2 窗口函数种类](https://github.com/datawhalechina/team-learning-sql/blob/main/Task05%EF%BC%9ASQL%E9%AB%98%E7%BA%A7%E5%A4%84%E7%90%86.md#52-%E7%AA%97%E5%8F%A3%E5%87%BD%E6%95%B0%E7%A7%8D%E7%B1%BB)
46 | - [x] [5.3 窗口函数的的应用 - 计算移动平均](https://github.com/datawhalechina/team-learning-sql/blob/main/Task05%EF%BC%9ASQL%E9%AB%98%E7%BA%A7%E5%A4%84%E7%90%86.md#53-%E7%AA%97%E5%8F%A3%E5%87%BD%E6%95%B0%E7%9A%84%E7%9A%84%E5%BA%94%E7%94%A8---%E8%AE%A1%E7%AE%97%E7%A7%BB%E5%8A%A8%E5%B9%B3%E5%9D%87)
47 | - [x] [5.4 GROUPING运算符](https://github.com/datawhalechina/team-learning-sql/blob/main/Task05%EF%BC%9ASQL%E9%AB%98%E7%BA%A7%E5%A4%84%E7%90%86.md#54-grouping%E8%BF%90%E7%AE%97%E7%AC%A6)
48 |
49 | * Task06:综合练习
50 | - [x] [6.1 练习一: 各部门工资最高的员工(难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E4%B8%80-%E5%90%84%E9%83%A8%E9%97%A8%E5%B7%A5%E8%B5%84%E6%9C%80%E9%AB%98%E7%9A%84%E5%91%98%E5%B7%A5%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
51 | - [x] [6.2 练习二: 换座位(难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E4%BA%8C-%E6%8D%A2%E5%BA%A7%E4%BD%8D%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
52 | - [x] [6.3 练习三: 分数排名(难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E4%B8%89--%E5%88%86%E6%95%B0%E6%8E%92%E5%90%8D%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
53 | - [x] [6.4 练习四:连续出现的数字(难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E5%9B%9B%E8%BF%9E%E7%BB%AD%E5%87%BA%E7%8E%B0%E7%9A%84%E6%95%B0%E5%AD%97%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
54 | - [x] [6.5 练习五:树节点 (难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E4%BA%94%E6%A0%91%E8%8A%82%E7%82%B9-%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
55 | - [x] [6.6 练习六:至少有五名直接下属的经理 (难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E5%85%AD%E8%87%B3%E5%B0%91%E6%9C%89%E4%BA%94%E5%90%8D%E7%9B%B4%E6%8E%A5%E4%B8%8B%E5%B1%9E%E7%9A%84%E7%BB%8F%E7%90%86-%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
56 | - [x] [6.7 练习七: 分数排名 (难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E4%B8%83-%E5%88%86%E6%95%B0%E6%8E%92%E5%90%8D--%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
57 | - [x] [6.8 练习八:查询回答率最高的问题 (难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E5%85%AB%E6%9F%A5%E8%AF%A2%E5%9B%9E%E7%AD%94%E7%8E%87%E6%9C%80%E9%AB%98%E7%9A%84%E9%97%AE%E9%A2%98-%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
58 | - [x] [6.9 练习九:各部门前3高工资的员工(难度:中等)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E4%B9%9D%E5%90%84%E9%83%A8%E9%97%A8%E5%89%8D3%E9%AB%98%E5%B7%A5%E8%B5%84%E7%9A%84%E5%91%98%E5%B7%A5%E9%9A%BE%E5%BA%A6%E4%B8%AD%E7%AD%89)
59 | - [x] [6.10 练习十:平面上最近距离 (难度: 困难)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E5%8D%81%E5%B9%B3%E9%9D%A2%E4%B8%8A%E6%9C%80%E8%BF%91%E8%B7%9D%E7%A6%BB-%E9%9A%BE%E5%BA%A6-%E5%9B%B0%E9%9A%BE)
60 | - [x] [6.11 练习十一:行程和用户(难度:困难)](https://github.com/datawhalechina/team-learning-sql/blob/main/Task06%EF%BC%9A%E7%BB%BC%E5%90%88%E7%BB%83%E4%B9%A0.md#%E7%BB%83%E4%B9%A0%E5%8D%81%E4%B8%80%E8%A1%8C%E7%A8%8B%E5%92%8C%E7%94%A8%E6%88%B7%E9%9A%BE%E5%BA%A6%E5%9B%B0%E9%9A%BE)
61 |
62 |
63 |
64 | ## 常见问题
65 |
66 | - **在线教程页面无法打开**:
67 |
68 | 测试中存在部分人打不开在线教程的情况。
69 |
70 | 部分小伙伴反馈尝试切换浏览器后可以正常打开了,如果仍然不行,最有效的解决办法是科学上网。
71 |
72 | - **无法加载图片的解决办法**:
73 |
74 | 根本解决办法还是科学上网,也可以尝试修改host文件看下是否能解决。
75 |
76 | [windows解决方案:修改host文件](https://blog.csdn.net/u011583927/article/details/104384169)
77 |
78 |
79 | ## 致谢
80 |
81 | 感谢以下Datawhale成员对项目推进作出的贡献(排名不分先后):
82 |
83 |
84 | 贡献者名单
85 |
86 |
87 | 成员 |
88 | 个人简介及贡献 |
89 | 个人主页 |
90 |
91 |
92 |
93 |
94 | 王复振 |
95 | Datawhale成员,项目负责人,Task00/01/03内容构建 |
96 | CSDN博客 |
97 |
98 |
99 | 杨煜 |
100 | 数据分析师,公众号:BI数据可视化,Datawhale成员,Task05/06内容构建 |
101 | |
102 |
103 |
104 | 闫钟峰 |
105 | 图书馆员,Datawhale成员,Task00/04内容构建 |
106 | |
107 |
108 |
109 | 杨梦迪 |
110 | 上海大学硕士,Datawhale成员,Task02内容构建 |
111 | |
112 |
113 |
114 | 苏鹏 |
115 | 东北大学硕士,Datawhale成员,Task00/01/03内容构建 |
116 | Github |
117 |
118 |
119 | 红星 |
120 | 广东工业大学,Datawhale成员,内测小组成员 |
121 | |
122 |
123 |
124 | 张晋 |
125 | 北京理工大学,Datawhale成员,内测小组成员 |
126 | |
127 |
128 |
129 | 汪健麟 |
130 | 电子科技大学硕士,Datawhale成员,内测小组成员 |
131 | |
132 |
133 |
134 | 苏丽敏 |
135 | 北京理工大学硕士,Datawhale成员,助教 |
136 | |
137 |
138 |
139 |
140 |
141 |
142 | ## 关注我们
143 |
144 | > "Datawhale是一个专注AI领域的开源组织,以“for the learner,和学习者一起成长”为愿景,构建对学习者最有价值的开源学习社区。关注我们,一起学习成长。"
145 |
146 |
147 |
--------------------------------------------------------------------------------
/SQL基础教程.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/datawhalechina/team-learning-sql/b3208831249a361292380d4655f5b7280cbff51c/SQL基础教程.pdf
--------------------------------------------------------------------------------
/Task00:绪论 - 环境搭建.md:
--------------------------------------------------------------------------------
1 | # 本章重点:
2 | * 在电脑上安装MySQL数据库系统
3 | * 安装客户端并连接到本机上的MySQL数据库
4 | * 使用提供的脚本创建本教程所使用的示例数据库
5 | # 1. MySQL 8.0 的安装
6 |
7 | 考虑到大家所使用的操作系统的不同, 本教程分别提供了 windows 10, macOS和centos平台上的MySQL 8.0 的安装流程, 你可根据自己所使用电脑的操作系统选择以下三节中的一节进行学习和安装.
8 |
9 | ## 1.1 windows 下 MySQL 8.0 的下载安装
10 |
11 | 首先以最常见的 win10 为例, 介绍 MySQL8.0 的下载安装.
12 |
13 | ### 1.1.1 下载
14 |
15 | MySQL 针对个人用户和商业用户提供了不同的版本, MySQL 社区版(MySQL Community Edition) 是供个人用户免费下载的开源数据库, 本教程将以MySQL 社区版为例进行安装连接和SQL查询的讲解.
16 |
17 | MySQL 官网上的社区版软件的下载地址[https://dev.mysql.com/downloads/](https://dev.mysql.com/downloads/), 选择[MySQL Installer for Windows](https://dev.mysql.com/downloads/windows/)可以下载 windows 操作系统下的最新版 MySQL安装文件. 如果需要安装历史版本, 可以选择最后的[Download Archives](https://downloads.mysql.com/archives/)后选择[MySQL Installer](https://downloads.mysql.com/archives/installer/),然后在新页面里选择所需历史版本的社区版.
18 |
19 | 如果想下载本教程所使用的 MySQL 8.0.21.0, 也可以在百度⽹盘下载,
20 |
21 | 下载链接:[https://pan.baidu.com/s/1SOtMoVqqRXwa2qD0siHcIg](https://pan.baidu.com/s/1SOtMoVqqRXwa2qD0siHcIg)提取码:80lf
22 |
23 | 备用下载链接:[https://pan.baidu.com/s/1zK2vj50DvuAee-EqAcl-0A](https://pan.baidu.com/s/1zK2vj50DvuAee-EqAcl-0A)提取码:80lf
24 |
25 | 我们接下来以文档写作时的最新版 MySQL 8.0.21 为例, 进行下载安装的介绍.
26 |
27 | 进入到[MySQL Installer for Windows](https://dev.mysql.com/downloads/windows/)页面后, 选择下载下方的完整安装程序.
28 |
29 | 
30 |
31 | 在下载页面选择下方的不注册,仅下载.
32 |
33 | 
34 |
35 | 完成下载后, 得到一个后缀为msi的安装文件.
36 |
37 | 
38 |
39 | ### 1.1.2 安装
40 |
41 | 找到刚才下载好的msi文件, 双击开始安装. 初学者建议采用完全安装模式(Full)进行安装:
42 |
43 | 
44 |
45 | 选择安装路径和数据存放路径, 二者都可以选择在非系统盘(注意要点击最右侧的按钮进行选择, 不要直接在文本框中修改安装路径).
46 |
47 | 
48 |
49 | 完全安装模式下, 部分模块会依赖其他其他组件(每台电脑上列出的依赖项很可能会有不同).
50 |
51 | 
52 |
53 | 如果你的电脑之前没有安装过这些组件, 则需要额外进行安装, 此处点击 Execute 按钮即可:
54 |
55 | 
56 |
57 | 在这些所依赖的组件的安装过程中, 只需要一路选择"同意"并逐个安装就可以了:
58 |
59 | 
60 |
61 | 安装好⼀个组件后, 点击关闭按钮, ⾃动开始安装下⼀个组件(这一步根据操作系统版本可能会略有不同)
62 |
63 | 
64 |
65 | 
66 |
67 | 
68 |
69 | 正常情况下,会将所有组件安装成功.但可能会有个别组件未安装成功. 个别组件没有呈现绿⾊是因为你的电脑中缺少某个程序, 例如, 如果你的电脑没有安装 Python 环境, 则该项目就不会呈现绿色. 待下边剩下 3 个按钮且上⽅⼤部分组件为绿色时, 即可点击 Next:
70 |
71 | 
72 |
73 | 如果有个别组件未安装成功, 此时可以先选择 Yes, 忽略个别组件的安装.
74 |
75 | 
76 |
77 | 点击 Excute, 开始安装服务器软件MySQL Server, 连接和查询软件MySQL Workbench及其他相关软件等内容.
78 |
79 | 
80 |
81 | 稍等片刻, 安装完成后, 点击 Next
82 |
83 | 
84 |
85 | 
86 |
87 | 下图这一步是选是否以集群方式安装 MySQL, 我们选择默认的第一个, 然后点击 Next:
88 |
89 | 
90 |
91 | 此处上边的各种相关配置保持默认即可,**勾选最下边的"Show Advanced and Logging Options"框,**然后点击 Next:
92 |
93 | 
94 |
95 | 下图是密码强度的设置, 第⼀种模式为强密码校验模式, MySQL 8.0 推荐使⽤最新的数据库和客户端, 更换了加密插件, 者可能导致第三⽅客户端⼯具⽆法连接数据库.
96 |
97 | 第⼆种加密⽅式沿袭了 MySQL 5.x 的加密⽅式, 对第三⽅⼯具连接不敏感, 我们仅为了学习 SQL 查询, 并不需要很高的安全性, 因此此处请务必选择第二种⽅式(非常重要):
98 |
99 | 
100 |
101 | 在这一步设置 MySQL 的 root 账户密码, 由于上一步选择了第二个选项, 因此这里可以设置为较简单容易记忆的而密码, 例如"123456". 建议设置⽐较简单的密码, 并将密码记录下来以防遗忘, 忘记密码是⼀件麻烦事.
102 |
103 | 
104 |
105 | 此处保持默认即可, 如果 windows service name 右侧有⻩⾊警告图标显示, 表示名称重复, ⼿动更换⼀个名称即可, 然后点击 Next:
106 |
107 | 
108 |
109 | Logging Options 这里使用默认设置即可, 我们的学习中暂时用不到这些设置, 直接点击 Next:
110 |
111 | 
112 |
113 | 下图是设置是否大小写敏感的. 这一步非常重要,**由于windows系统是大小写不敏感的, 请大家务必使用第一个选项Lower Case**.
114 |
115 | 
116 |
117 | 点击 Execute
118 |
119 | 
120 |
121 | 完成安装后, 在下图中点击 Finish 回到安装的主进程:
122 |
123 | 
124 |
125 | 在主进程界面点击 Next
126 |
127 | 
128 |
129 | 这一步无需任何选择, 直接点击 Finish
130 |
131 | 
132 |
133 | 进入到 Connect To Server 界面后, 输⼊刚才设置的密码, 点击 check 进⾏校验, 校验通过后 Status 会显示连接成功, 然后点击 Next
134 |
135 | 
136 |
137 | 点击 Excute 应用设置:
138 |
139 | 
140 |
141 | 上述步骤完成后, 点击 Finish
142 |
143 | 
144 |
145 | 回到安装主进程后, 点击 Next
146 |
147 | 
148 |
149 | 点击 Finish,完成安装.
150 |
151 | 
152 |
153 | 现在, 你的电脑上就已经安装了MySQL的服务器软件, 用于连接服务器进行查询的MySQL Workbench, 以及其他程序语言连接MySQL的驱动, 此外还安装了几个示例数据库, 但本教程将采用一书中的示例数据库, 该数据库的创建和数据导入将在本章第三节介绍.
154 |
155 |
156 | ## 1.2 macOS 下 MySQL 8.0 的下载安装
157 |
158 | MySQL 官网上社区版软件的下载地址[https://dev.mysql.com/downloads/](https://dev.mysql.com/downloads/), 选择[MySQL Community Server](https://dev.mysql.com/downloads/mysql/)可以进一步选择下载 macOS操作系统下的最新版 MySQL. 如果需要安装历史版本, 可以选择最后的[Download Archives](https://downloads.mysql.com/archives/)后选择[MySQL Installer](https://downloads.mysql.com/archives/installer/),然后在新页面里选择所需历史版本的社区版.
159 |
160 | 
161 |
162 | 然后选择下载dmg安装文件.
163 |
164 | 
165 |
166 | 点击下方的直接下载.
167 |
168 | 
169 |
170 | 下载的文件为:
171 |
172 | 
173 |
174 | 如果官网下载速度很慢, 或者希望下载本教程所使用的 MySQL 8.0.21.0, 也可以在百度⽹盘下载,
175 |
176 | 下载链接:[https://pan.baidu.com/s/1ka22UtzqFdOaIosrpKz92w](https://pan.baidu.com/s/1ka22UtzqFdOaIosrpKz92w)提取码: 8xh4
177 |
178 | 备用下载链接:[https://pan.baidu.com/s/1XeA_8PQvvRePEdZ5ayOT-Q](https://pan.baidu.com/s/1XeA_8PQvvRePEdZ5ayOT-Q)提取码:8xh4
179 |
180 |
181 | 我们接下来以文档写作时的最新版为 8.0.21 为例, 进行下载安装讲解.
182 |
183 | 在mac上直接双击dmg文件就可以开始安装了. 我们只选择了安装MySQL Community Server, 因此安装过程较为简单.
184 |
185 | 
186 |
187 | 
188 |
189 | 
190 |
191 | 注意, 在配置MySQL服务器这一步, 最好选择下边的选项, 这样就可以使用简单密码.
192 |
193 | 
194 |
195 | 在 Configuration 接下来的步骤需要设置密码, 如果上一步选择了第二个选项, 这里就可以使用比较简单的密码. 请务必牢记自己设置的密码.
196 |
197 | 
198 |
199 | 注意, 如果在前一步选择使用了MySQL8.0强密码, MySQL安装过程中会自动生成一个随机密码, 类似于下图这种形式:
200 |
201 | 
202 |
203 | 此时请截图保留该密码, 并在安装完成后, 使用该密码登录并重新设置密码. 由于选择使用了强密码, 此时设置密码必须使用大小写字母数字和特殊符号的组合.
204 |
205 | 完成安装后, 打开电脑的系统偏好设置, 会出现MySQL的服务标识.
206 |
207 | 
208 |
209 | 正确安装MySQL后, 打开上述截图中的MySQL之后会看到如下界面, 在这里可以启动和停止MySQL服务, 以及配置MySQL是否随电脑启动而自动启动.
210 |
211 | 
212 |
213 | 安装之后, 如果我们直接在终端输入mysql, 会提示找不到命令, 需要配置一下环境变量才可以, 输入以下命令:
214 |
215 | ```plain
216 | PATH="$PATH":/usr/local/mysql/bin
217 | ```
218 | 再通过终端输入mysql登录命令后, 就可以看到mysql的交互式界面了.
219 | 
220 |
221 | 然后输入以下内容, 将自己电脑的mysql路径配置到环境变量中, 如果在安装过程中你没修改过安装路径, 那么你的电脑上MySQL的路径应该和下述代码中所使用的路径是一致的:
222 |
223 | ```plain
224 | export PATH=$PATH:/usr/local/mysql/bin
225 | ```
226 | 
227 |
228 | 运行上述配置后, 通过输入下面这条命令使修改生效
229 |
230 | ```plain
231 | source ~/.bash_profile
232 | ```
233 | 接下来, 在你的终端中输入命令来登录到MySQL
234 | ```plain
235 | mysql -u root -p
236 | ```
237 | 然后需要输入你刚才设置的密码(如果你选择了强密码, 则这里需要输入你查到的随机密码), 如果看到以下界面, 则表示你的电脑上: 1.MySQL8.0已经正确安装, 2.已经正确配置了MySQL8.0的环境变量,并且3.已经启动MySQL服务器程序. 如果并没有出现下属界面, 请按照上述三个顺序逐个检查.
238 |
239 | 
240 |
241 | 使用终端(或者windows下的命令行)与MySQL进行交互是非常便捷和高效的, 但是对于平时不怎么使用终端的普通人来说, 使用终端在做数据查询时, 在查询结果的显示和导出方面有诸多不便, 特别是当我们对 SQL 查询不熟练的时候, 这种方式很不利于我们进行查询语句的调试. 因此本教程将选择查询界面更加友好的客户端工具来连接数据库, 这种通过终端连接MySQL的方式暂时不再使用.
242 |
243 | 接下来请安装跳转到2.1节安装MySQL Workbench并连接本机的MySQL服务.
244 |
245 | >注:
246 | >macOS上的SQL查询工具也有很多其他的选择, 比如DBeaver(开源, 免费), DataGrip(需付费购买,提供30天的免费试用期, 学生使用学校的邮箱可以申请到一年的免费使用权)等,可参考知乎上的问题 :
247 | >Mac平台上有哪些好的SQL 数据库开发工具?[https://www.zhihu.com/question/20498949](https://www.zhihu.com/question/20498949)
248 | ##
249 |
250 |
251 | 
252 |
253 |
254 | ## 1.3 Linux 下 MySQL 8.0 的下载安装
255 |
256 | 本节我们以 centos 版本的 Linux 操作系统为例, 介绍下载安装 MySQL8.0.21 的过程. 示例操作系统的linux 版本:centos-release-7-7.1908.0.el7.centos.x86_64
257 |
258 | 在 CentOS 系统中默认是安装了 MariaDB 的, 但是我们需要的是 MySQL, 我们可以直接下载安装 MySQL, 安装 MySQL 可以覆盖 MariaDB.
259 |
260 | >关于 MariaDB:
261 | >MariaDB 数据库管理系统是 MySQL 的一个分支, 主要由开源社区在维护, 采用 GPL 授权许可. 开发这个分支的原因之一是:甲骨文公司收购了 MySQL 后, 有将 MySQL 闭源的潜在风险, 因此社区采用分支的方式来避开这个风险. MariaDB 的目的是完全兼容 MySQL, 包括 API 和命令行, 使之能轻松成为 MySQL 的代替品. 但在两个分支经过了几年的各自迭代之后, 在一些方面二者出现了一些差异.
262 | ###
263 | ### 1.3.1 安装步骤:
264 |
265 | 首先, 从[MySQL官网](https://dev.mysql.com/downloads/repo/yum/)下载 MySQL 的 Yum Repository. 根据 CentOS 和 MySQL 的版本,选择下载相对应的文件. 本文选择红色方框的文件.
266 |
267 | 
268 |
269 | Yum 是一个基于 rpm 的软件包管理器, 它可以从指定的服务器自动下载 RPM 包并且安装, 可以自动处理依赖性关系, 并且一次安装所有依赖的软体包, 无须繁琐地一次次下载、安装.
270 |
271 | 下载命令:
272 |
273 | ```plain
274 | wget https://dev.mysql.com/get/mysql80-community-release-el7-2.noarch.rpm
275 | ```
276 | 用 yum 命令安装下载好的 rpm 包.
277 | ```plain
278 | yum -y install mysql80-community-release-el7-2.noarch.rpm
279 | ```
280 | 安装 MySQL 服务器.
281 | ```plain
282 | yum -y install mysql-community-server
283 | ```
284 | 这一步由于要下载安装文件, 可能会花一些时间. 安装完成后就会覆盖掉之前的 mariadb.
285 | 当出现如下图所示的内容,则代表 MySQL 就安装完成了.
286 |
287 | 
288 |
289 | ### 1.3.2 MySQL 数据库设置
290 |
291 | 启动 MySQL
292 |
293 | ```plain
294 | systemctl start mysqld.service
295 | ```
296 | 查看 MySQL 运行状态, Active 后面的状态代表启功服务后为 active (running), 停止后为 inactive (dead), 运行状态如图:
297 | ```plain
298 | systemctl status mysqld.service
299 | ```
300 | 
301 |
302 | 重新启动 Mysql 和停止 Mysql 的命令如下:
303 |
304 | ```plain
305 | service mysqld restart #重新启动 Mysql
306 | systemctl stop mysqld.service #停止 Mysql
307 | ```
308 | 此时 MySQL 已经开始正常运行, 不过要想进入 MySQL 还得先找出此时 root 用户的密码, 通过如下命令可以在日志文件中找出密码:
309 | 为了加强安全性, MySQL8.0 为 root 用户随机生成了一个密码, 在 error log 中, 关于 error log 的位置, 如果安装的是 RPM 包, 则默认是/var/log/mysqld.log. 只有启动过一次 mysql 才可以查看临时密码
310 |
311 | 使用命令:
312 |
313 | ```plain
314 | grep 'temporary password' /var/log/mysqld.log
315 | ```
316 | 查看初始的随机密码:
317 | 
318 |
319 | 登录 root 用户
320 |
321 | ```plain
322 | mysql -u root -p
323 | ```
324 | 然后输入上述查到的初始密码. 登录后还不能做任何查询或建库操作, 因为 MySQL 默认必须修改初始的随机密码之后才能操作数据库,否则会报错:
325 |
326 | 
327 |
328 | 修改密码为"123456", 注意结尾要有分号, 表示语句的结束.
329 |
330 | ```plain
331 | ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
332 | ```
333 | 这里有个问题, 新密码设置的时候如果设置的过于简单会报错:
334 |
335 | 
336 |
337 | 原因是因为 MySQL 有密码设置的规范, 具体是与 validate_password_policy 的值有关:
338 |
339 | 
340 |
341 | MySQL 完整的初始密码规则可以通过如下命令查看:
342 |
343 | 
344 |
345 | 密码的长度是由 validate_password_length 决定的, 而 validate_password_length 的计算公式是:
346 |
347 | ```plain
348 | validate_password_length = validate_password_number_count + validate_password_special_char_count + (2 * validate_password_mixed_case_count)
349 | ```
350 | 如果想要设置简单的密码必须要修改约束, 修改两个全局参数:
351 | * **validate_password_policy**代表密码策略, 默认是 1:符合长度, 且必须含有数字, 小写或大写字母, 特殊字符. 设置为 0 判断密码的标准就基于密码的长度了. 一定要先修改两个参数再修改密码
352 | ```plain
353 | mysql> set global validate_password.policy=0;
354 | ```
355 | * **validate_password_length**代表密码长度, 最小值为 4
356 | ```plain
357 | mysql> set global validate_password.length=4;
358 | ```
359 | 修改完,如图
360 |
361 | 
362 |
363 | 此时密码就可以设置的很简单, 例如 1234 之类的. 到此数据库的密码设置就完成了.
364 |
365 | 但此时还有一个问题, 就是因为安装了 Yum Repository, 以后每次 yum 操作都会自动更新, 如不需要更新, 可以把这个 yum 卸载掉:
366 |
367 | ```plain
368 | [root@localhost ~]# yum -y remove mysql80-community-release-el7-2.noarch
369 | ```
370 |
371 | 在 CentOS 中 MySQL 的主要配置所在的目录:
372 |
373 | ```plain
374 | 1 /etc/my.cnf 这是 mysql 的主配置文件
375 | 2 /var/lib/mysql mysql 数据库的数据库文件存放位置
376 | 3 /var/log mysql 数据库的日志输出存放位置
377 | ```
378 | 一些可能会用到的设置:
379 |
380 | 设置表名为大小写不敏感:
381 |
382 | 1.用root帐号登录后, 使用命令
383 |
384 | ```plain
385 | systemctl stop mysqld.service
386 | ```
387 | 停止MySQL数据库服务,修改vi /etc/my.cnf,在[mysqld]下面添加
388 | ```plain
389 | lower_case_table_names=1
390 | ```
391 | 这里的参数 0 表示区分大小写,1 表示不区分大小写.
392 | 2.做好数据备份,然后使用下述命令删除数据库数据(删除后, 数据库将恢复到刚安装的状态)
393 |
394 | ```plain
395 | rm -rf /var/lib/mysql
396 | ```
397 | 3.重启数据库 ,此时数据库恢复到初始状态.
398 | ```plain
399 | service mysql start
400 | ```
401 | 4.重复安装时的操作, 查找临时密码
402 | ```plain
403 | grep 'temporary password' /var/log/mysqld.log
404 | ```
405 | 5.修改密码. 密码8位以上, 大小写符号数据. 如想要使用简单密码, 需按照上述安装流程中的步骤进行操作.
406 | ```plain
407 | ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '****';update user set host = "%" where user='root';
408 | ```
409 | 6.刷新MySQL的系统权限相关表
410 | ```plain
411 | FLUSH PRIVILEGES;
412 | ```
413 | 此时, MySQL的表名的大小写不再敏感.
414 | ### 1.3.3 设置远程连接:
415 |
416 | 如果你想要在另外一台电脑上连接 centos 上安装的 MySQL, 那么还需要一些其他的设置.
417 |
418 | 首先需要将 MySQL 设置为可以远程连接,设置 mysql 库的 user 表中帐号的 host 为%, %表示可以从任意 ip 连接 mysql, 为了安全性, 也可以设置为你自己所用于连接 centos 上 MySQL 的电脑所使用的 IP.
419 |
420 | 其次, MYSQL 8.0 内新增加 mysql_native_password 函数,通过更改这个函数密码来进行远程连接.
421 |
422 | 例如,更改 root 用户的 native_password 密码
423 |
424 | ```plain
425 | ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY'MyPass@123';
426 | ```
427 | 接下来为 centos 的防火墙开启 MySQL 所使用的 3306 端口,并重新加载防火墙:
428 | ```plain
429 | firewall-cmd --zone=public --add-port=3306/tcp --permanent
430 | firewall-cmd --reload
431 | ```
432 | 完成上述设置后, 重新启动 MySQL 服务:
433 | ```plain
434 | service mysqld restart #重新启动 Mysql
435 | ```
436 | 最后, 在另外一台电脑上, 使用下一节介绍的各类客户端工具进行连接测试.
437 | # 2. 连接 MySQL 并执行 SQL 查询
438 |
439 | 在安装成功MySQL后, 我们可以通过开始菜单->控制面板->管理工具->服务中查找并开启或关闭MySQL服务. 开启服务后, MySQL Server将以后台服务的形式在你的电脑上运行. 如果想要进行查询, 还需要使用命令行工具或者其他更加友好的应用程序连接到MySQL服务.
440 |
441 | ##
442 | ## 2.0 使用命令行方式连接MySQL服务
443 |
444 | 连接数据库的最基本的⽅式, 是使用命令⾏. 以win10为例, 在完成 MySQL 服务的安装后, 在开始菜单找到刚才安装好的 MySQL 8.0 命令⾏⼯具,单击即可打开:
445 |
446 | 
447 |
448 | 输⼊你在安装过程中为root用户设置的密码即可连接到数据库, 看到如下界⾯, 表示数据库安装成功,并且你已经使用命令行连接到了数据库(图中红框表示数据库版本), 在最后的 "mysql>" 后即可输入SQL命令执行各种数据库操作.
449 |
450 | 
451 |
452 | 但是使用命令行在做数据查询时, 在查询结果的显示和导出方面有诸多不便, 特别是当我们对 SQL 查询不熟练的时候, 这种方式不利于我们进行查询语句的修改和调试. 因此本教程将选择查询界面更加友好的客户端工具(使用MySQL Workbench)来连接数据库, 这种通过命令行连接的方式暂时不再使用.
453 |
454 | >常见的可用于连接MySQL数据库并进行查询等操作的管理工具包括开源软件 MySQL Workbench, HeidiSQL和DBeaver, 以及商业软件Navicat(有免费版和14天试用版),SQLyog(有免费的社区版)和DataGrip等等.
455 | ##
456 | ## 2.1 使用 MySQL Workbench 连接 MySQL
457 |
458 | MySQL Workbench 是 MySQL 官方的客户端工具, 支持windows, macOS和Linux. 对于windows用户, 我们在安装 MySQL 的时候由于选择的是完整安装模式, 因此也同时安装了这个工具, 对于macOS的用户, 可以在[https://dev.mysql.com/downloads/workbench/](https://dev.mysql.com/downloads/workbench/)选择macOS版本进行下载安装. MySQL Workbench 是一款功能强大的数据库管理工具, 它既可以用于设计数据库, 也可以用于连接数据库进行查询, 我们这个课程主要使用它的连接数据库进行查询的功能.
459 |
460 | 如果你使用的是windows 7 操作系统, 打开 MySQL Workbench 后, 会有如下提示:
461 |
462 | 
463 |
464 | 这是说 MySQL 不再维护win7系统下的MySQL Workbench, 但并不影响使用. 打开MySQL Workbench后, 使用快捷键 ctrl+u,或者点击菜单栏里的 Database->Connect to Database, 进入数据库连接的设置界面, 如下图所示:
465 |
466 | 
467 |
468 | 然后如下图红框中设置连接本机的 MySQL8.0, 输入密码并点击 OK:
469 |
470 | 
471 |
472 | 如果弹出如下对话框,表示 MySQL 服务器设置为对于表名和列名的大小写敏感, 但由于 windows 系统默认的是大小写不敏感, 因此当表名或列名有大写字母时, 即使写的 SELECT 语句中正确地使用了大写的表名, 程序也无法正确执行. 这时候建议大家在开始学习查询之前,把表名逐一更改为小写.
473 |
474 | 
475 |
476 | 打开后的界⾯
477 |
478 | 
479 |
480 | 在中间的编辑器里, 就可以写 SQL 查询了.
481 |
482 | 下一次打开软件时, 可以直接点击保存的数据库连接, 不需要先进行设置后再连接了:
483 |
484 | 
485 |
486 | ## 2.2 [选学]使用 HeidiSQL 连接 MySQL
487 |
488 | HeidiSQL 是一款功能非常强大的开源免费的数据库客户端软件, 采用 Delphi 语言开发, 支持 Windows 操作系统. 支持 MySQL、Postgresql、MariaDB、Percona Server 和微软的 SQL Server, 官网下载地址:[https://www.heidisql.com/download.php](https://www.heidisql.com/download.php), 下载 portable 版本后, 解压缩就可以使用.
489 |
490 | 
491 |
492 | 点击文件夹中的 heidisql.exe, 在弹出对话框里点击"新建", 然后填写密码, 再点击"打开"即可连接到本机上安装的 MySQL 数据库.
493 |
494 | 
495 |
496 | 软件的主界面如图所示:
497 |
498 | 
499 |
500 | ## 2.3 [选学]使用 DBeaver 连接 MySQL
501 |
502 | DBeaver 是一款基于 JAV 开发的**免费和开源(GPL)**的通用数据库管理工具和 SQL 客户端, 提供windows, macOS和Linux全平台支持, 能够连接包括 MySQL, PostgreSQL, Oracle, DB2, MSSQL, Sybase, Mimer, HSQLDB, Derby 等主流数据库软件在内的绝大多数兼容 JDBC 驱动的数据库. DBeaver 提供一个图形界面用来查看数据库结构、执行 SQL 查询和脚本, 浏览和导出数据, 处理 BLOB/CLOB 数据, 修改数据库结构等等.
503 |
504 | 由于是开源软件, 大家可直接从官网([https://dbeaver.io/](https://dbeaver.io/))下载, 安装完成后, 打开软件, 点击"文件"菜单下的"新建连接"图标, 并选择 MySQL:
505 |
506 | 
507 |
508 | 然后点击下一步:
509 |
510 | 
511 |
512 | 在下方弹出的设置窗口中, "服务器地址"使用默认的localhost, "数据库"暂时留空, 然后在下方填入自己设置的密码, 最后点击测试连接.
513 |
514 | 
515 |
516 | 本次学习主要使用一个新建的 shop 数据库, 但因为相关数据我们还没导入(建库建表及数据导入的脚本在本章第三节),因此数据库这里先留空. 等下一步导入数据后, 再进一步修改连接参数.
517 |
518 | 
519 |
520 | 首次连接时会提示需要下载驱动程序,
521 |
522 | 完成驱动程序的下载后, 再次点击"测试连接",如果弹出如下对话框, 则表示连接成功:
523 |
524 | 
525 |
526 | 点击确定并保存连接后, 以后就可以直接双击这个连接进行数据库连接了. 如果需要保存多个数据库连接, 可以使用快捷键 F2 或选中当前连接并点击鼠标右键后选择"重命名"为当前连接起一个便于识别的名称.
527 |
528 | 
529 |
530 | 接下来就可以开始写你的第一个 SQL 语句了: 如上图这样,选中刚刚保存的连接, 鼠标右键选第一个按钮"SQL 编辑器", 或者直接使用快捷键 F3, 就会打开一个 SQL 编辑器, 然后就可以在这里编写 SQL 语句了.
531 |
532 | 例如我们可以使用如下语句完成本教程所使用的示例数据库的创建:
533 |
534 | 
535 |
536 | 注意, 在使用创建数据库的语句时, 是无需在红框中选中数据库的, 但其他所有的创建表,导入数据, 和最常用的查询语句, 都需要选中相应的数据库. 在执行上述语句后, 我们可以回到连接设置里, 把默认数据库连接改为刚才创建的 shop.
537 |
538 | 
539 |
540 | ## 2.4 [选学]使用 Navicat 连接 MySQL
541 |
542 | Navicat 包含了一系列的功能强大的数据库管理软件, 主要有: 完整功能版的 Navicat Premium, 以及专门用于MySQL数据库管理的 Navicat for MySQL, 用于PostgreSQL数据库管理的 Navicat forPostgreSQL, 用于SQL Server数据库管理的 Navicat for SQL Server, 用于Oracle数据库管理的 Navicat for Oracle, 等等, 但它提供的免费的版本 Navicat Lite 已足够本次课程使用, 除此之外, 上述的其他软件均为收费软件.
543 |
544 | >注:
545 | >Navicat 官网已经不再提供 Navicat Lite 的下载了, 但可以通过搜索引擎找到 Navicat Lite 的历史版本的下载链接. 此外, 也可以从 Navicat 官网下载 Navicat Premium 或 Navicat for MySQL 的14天试用版.
546 | ## 2.5 [选学]使用 SQLyog 连接 MySQL
547 |
548 | SQLyog 是业界著名的 Webyog 公司出品的一款简洁高效、功能强大的图形化 MySQL 数据库管理工具. SQLyog 的企业版是收费软件, 但该软件也提供了社区版供大家使用, 虽然在功能上有些限制, 但对于本课程已经足够用了. SQLyog 社区版的下载地址为[https://github.com/webyog/sqlyog-community/wiki/Downloads](https://github.com/webyog/sqlyog-community/wiki/Downloads)
549 |
550 |
551 | ## 2.6 [选学]DataGrip的安装和连接MySQL
552 |
553 | DataGrip是大名鼎鼎的 JetBrains 出品的数据库工具, 支持windows, macOS和Linux操作系统.
554 |
555 |
556 | 1. 创建学习用的数据库
557 |
558 | 根据《SQL基础教程》提供的MySQL版本的数据库,数据表的创建以及数据导入的代码, 经过一些修改, 创建了一份 sql 脚本, 运行该脚本可以一步到位地创建本文档所需的数据库shop及其中所有的表,并插入本教程所需要的所有数据
559 |
560 | 由于本教程聚焦于面向初学者介绍SQL查询, 对于数据库的创建, 表的创建和数据导入, 以及数据更新, 暂时不做深入介绍,有兴趣和需要的读者可参考《SQL基础教程》1-4,1-5,以及第四章.
561 |
562 | 下述SQL脚本可用于创建本教程所使用的示例数据库shop以及数据库中表的创建和数据的插入.
563 |
564 | 见《附录3 - shop.sql》
565 |
566 | >SQL 脚本的一些要点-- v 9.08
567 | >>0.存储引擎使用 InnoDB, 字符集改为 utf8mb4 以更好地支持中文.
568 | >1.所有表名所使用的英文字母都改为小写(后续章节中,SQL 查询中的表名也需要相应修改为小写)
569 | >2.所有列名所使用的英文字母确认为小写(后续章节中,SQL 查询中的列名也需要相应修改为小写)
570 | >3.存在问题的数据, 例如 inventoryproduct 表的 inventory_id 列应为 P 开头的, 已修正为正确的数据.
571 | >4.需测试 SQL 脚本在命令行及各个客户端中是否能被正确执行.
572 | >* MySQL Workbench 已测试通过(在win10 使用 MySQL Workbench 8.0.21)
573 | >* DBeaver 已测试通过(使用"执行 SQL 脚本(CTR+x)") (在win10 使用 DBeaver7.2.0)
574 | >* HeidiSQL 已测试通过(在win10 使用HeidiSQL 11.0.0)
575 | >* navicat 已测试通过(在win10&win7 使用 navicat premium 15.0.17)
576 | >* sqlyog 已测试通过(在win10 使用 SQLyog 12.09)
577 | >* 命令行 win10 下测试未通过. 插入中文数据时提示" Data too long for column 'product_name' at row 1"
578 | #
579 |
580 |
581 |
--------------------------------------------------------------------------------
/Task01:初识数据库.md:
--------------------------------------------------------------------------------
1 | 本章主要讲解数据库安装和数据库基本介绍,考虑易用性及普及度,本课程采取mysql进行教学。
2 |
3 | # 1.1 初识数据库
4 |
5 | 数据库是将大量数据保存起来,通过计算机加工而成的可以进行高效访问的数据集合。该数据集合称为数据库(Database,DB)。用来管理数据库的计算机系统称为数据库管理系统(Database Management System,DBMS)。
6 |
7 | ### 1.1.1 DBMS的种类
8 |
9 | DBMS 主要通过数据的保存格式(数据库的种类)来进行分类,现阶段主要有以下 5 种类型.
10 |
11 | - 层次数据库(Hierarchical Database,HDB)
12 |
13 | - 关系数据库(Relational Database,RDB)
14 |
15 | - Oracle Database:甲骨文公司的RDBMS
16 | - SQL Server:微软公司的RDBMS
17 | - DB2:IBM公司的RDBMS
18 | - PostgreSQL:开源的RDBMS
19 | - MySQL:开源的RDBMS
20 |
21 | 如上是5种具有代表性的RDBMS,其特点是由行和列组成的二维表来管理数据,这种类型的 DBMS 称为关系数据库管理系统(Relational Database Management System,RDBMS)。
22 |
23 | - 面向对象数据库(Object Oriented Database,OODB)
24 |
25 | - XML数据库(XML Database,XMLDB)
26 |
27 | - 键值存储系统(Key-Value Store,KVS),举例:MongoDB
28 |
29 | 本课程将向大家介绍使用 SQL 语言的数据库管理系统,也就是关系数据库管理系统(RDBMS)的操作方法。
30 |
31 | ### 1.1.2 RDBMS的常见系统结构
32 |
33 | 使用 RDBMS 时,最常见的系统结构就是客户端 / 服务器类型(C/S类型)这种结构(图 1-3)
34 |
35 | 
36 |
37 | # 1.2 初识 SQL
38 |
39 | 
40 |
41 | 数据库中存储的表结构类似于excel中的行和列,在数据库中,行称为**记录**,它相当于一条记录,列称为**字段**,它代表了表中存储的数据项目。
42 |
43 | 行和列交汇的地方称为单元格,一个单元格中只能输入一条记录。
44 |
45 | SQL是为操作数据库而开发的语言。国际标准化组织(ISO)为 SQL 制定了相应的标准,以此为基准的SQL 称为标准 SQL。
46 |
47 | 完全基于标准 SQL 的 RDBMS 很少,通常需要根据不同的 RDBMS 来编写特定的 SQL 语句,原则上,本课程介绍的是标准 SQL 的书写方式。
48 |
49 | 根据对 RDBMS 赋予的指令种类的不同,SQL 语句可以分为以下三类.
50 |
51 | * DDL
52 |
53 | DDL(Data Definition Language,数据定义语言) 用来创建或者删除存储数据用的数据库以及数据库中的表等对象。DDL 包含以下几种指令。
54 |
55 |
56 |
57 | - CREATE : 创建数据库和表等对象
58 |
59 | - DROP : 删除数据库和表等对象
60 |
61 | - ALTER : 修改数据库和表等对象的结构
62 |
63 | * DML
64 |
65 |
66 |
67 | DML(Data Manipulation Language,数据操纵语言) 用来查询或者变更表中的记录。DML 包含以下几种指令。
68 |
69 | - SELECT :查询表中的数据
70 |
71 | - INSERT :向表中插入新数据
72 |
73 | - UPDATE :更新表中的数据
74 |
75 | - DELETE :删除表中的数据
76 |
77 | * DCL
78 |
79 | DCL(Data Control Language,数据控制语言) 用来确认或者取消对数据库中的数据进行的变更。除此之外,还可以对 RDBMS 的用户是否有权限操作数据库中的对象(数据库表等)进行设定。DCL 包含以下几种指令。
80 |
81 | - COMMIT : 确认对数据库中的数据进行的变更
82 |
83 | - ROLLBACK : 取消对数据库中的数据进行的变更
84 |
85 | - GRANT : 赋予用户操作权限
86 |
87 | - REVOKE : 取消用户的操作权限
88 |
89 |
90 | 实际使用的 SQL 语句当中有 90% 属于 DML,本书同样会以 DML 为中心进行讲解。
91 |
92 | ### 1.2.1 SQL的基本书写规则
93 |
94 | * SQL语句要以分号( ; )结尾
95 | * SQL 不区分关键字的大小写,但是插入到表中的数据是区分大小写的
96 | * win 系统默认不区分表名及字段名的大小写
97 | * linux / mac 默认严格区分表名及字段名的大小写
98 | * 本教程已统一调整表名及字段名的为小写,以方便初学者学习使用。··
99 | * 常数的书写方式是固定的
100 |
101 | 'abc', 1234, '26 Jan 2010', '10/01/26', '2010-01-26'......
102 |
103 | * 单词需要用半角空格或者换行来分隔
104 |
105 | SQL 语句的单词之间需使用半角空格或换行符来进行分隔,且不能使用全角空格作为单词的分隔符,否则会发生错误,出现无法预期的结果。
106 |
107 | 请大家认真查阅《附录1 - SQL 语法规范》,养成规范的书写习惯。
108 |
109 |
110 |
111 | ### 1.2.2 数据库的创建( CREATE DATABASE 语句)
112 |
113 | 语法:
114 |
115 | ```sql
116 | CREATE DATABASE < 数据库名称 > ;
117 | ```
118 | 创建本课程使用的数据库
119 | ```sql
120 | CREATE DATABASE shop;
121 | ```
122 | ### 1.2.3 表的创建( CREATE TABLE 语句)
123 |
124 | 语法:
125 |
126 | ```sql
127 | CREATE TABLE < 表名 >
128 | ( < 列名 1> < 数据类型 > < 该列所需约束 > ,
129 | < 列名 2> < 数据类型 > < 该列所需约束 > ,
130 | < 列名 3> < 数据类型 > < 该列所需约束 > ,
131 | < 列名 4> < 数据类型 > < 该列所需约束 > ,
132 | .
133 | .
134 | .
135 | < 该表的约束 1> , < 该表的约束 2> ,……);
136 | ```
137 | 创建本课程用到的商品表
138 |
139 | ```sql
140 | CREATE TABLE product
141 | (product_id CHAR(4) NOT NULL,
142 | product_name VARCHAR(100) NOT NULL,
143 | product_type VARCHAR(32) NOT NULL,
144 | sale_price INTEGER ,
145 | purchase_price INTEGER ,
146 | regist_date DATE ,
147 | PRIMARY KEY (product_id));
148 | ```
149 |
150 | ### 1.2.4 命名规则
151 |
152 | * 只能使用半角英文字母、数字、下划线(_)作为数据库、表和列的名称
153 | * 名称必须以半角英文字母开头
154 |
155 | 表1-3 商品表和 product 表列名的对应关系
156 |
157 | 
158 |
159 | ### 1.2.5 数据类型的指定
160 |
161 | 数据库创建的表,所有的列都必须指定数据类型,每一列都不能存储与该列数据类型不符的数据。
162 |
163 | 四种最基本的数据类型
164 |
165 | * INTEGER 型
166 |
167 | 用来指定存储整数的列的数据类型(数字型),不能存储小数。
168 |
169 |
170 |
171 | * CHAR 型
172 |
173 | 用来存储定长字符串,当列中存储的字符串长度达不到最大长度的时候,使用半角空格进行补足,由于会浪费存储空间,所以一般不使用。
174 |
175 | * VARCHAR 型
176 |
177 | 用来存储可变长度字符串,定长字符串在字符数未达到最大长度时会用半角空格补足,但可变长字符串不同,即使字符数未达到最大长度,也不会用半角空格补足。
178 |
179 | * DATE 型
180 |
181 | 用来指定存储日期(年月日)的列的数据类型(日期型)。
182 |
183 | ### 1.2.6 约束的设置
184 |
185 | 约束是除了数据类型之外,对列中存储的数据进行限制或者追加条件的功能。
186 |
187 | `NOT NULL`是非空约束,即该列必须输入数据。
188 |
189 | `PRIMARY KEY`是主键约束,代表该列是唯一值,可以通过该列取出特定的行的数据。
190 |
191 | ### 1.2.7 表的删除和更新
192 |
193 | * 删除表的语法:
194 | ```sql
195 | DROP TABLE < 表名 > ;
196 | ```
197 | * 删除 product 表
198 |
199 | 需要特别注意的是,删除的表是无法恢复的,只能重新插入,请执行删除操作时要特别谨慎。
200 |
201 | ```sql
202 | DROP TABLE product;
203 | ```
204 | - 添加列的 ALTER TABLE 语句
205 |
206 | ```sql
207 | ALTER TABLE < 表名 > ADD COLUMN < 列的定义 >;
208 | ```
209 | - 添加一列可以存储100位的可变长字符串的 product_name_pinyin 列
210 |
211 | ```sql
212 | ALTER TABLE product ADD COLUMN product_name_pinyin VARCHAR(100);
213 | ```
214 | - 删除列的 ALTER TABLE 语句
215 |
216 | ```sql
217 | ALTER TABLE < 表名 > DROP COLUMN < 列名 >;
218 | ```
219 | - 删除 product_name_pinyin 列
220 |
221 | ```sql
222 | ALTER TABLE product DROP COLUMN product_name_pinyin;
223 | ```
224 | ALTER TABLE 语句和 DROP TABLE 语句一样,执行之后无法恢复。误添的列可以通过 ALTER TABLE 语句删除,或者将表全部删除之后重新再创建。
225 | 【扩展内容】
226 |
227 | * 清空表内容
228 | ```sql
229 | TRUNCATE TABLE TABLE_NAME;
230 | ```
231 | 优点:相比`drop / delete`,`truncate`用来清除数据时,速度最快。
232 | * 数据的更新
233 |
234 | 基本语法:
235 |
236 | ```sql
237 | UPDATE <表名>
238 | SET <列名> = <表达式> [, <列名2>=<表达式2>...];
239 | WHERE <条件>; -- 可选,非常重要。
240 | ORDER BY 子句; --可选
241 | LIMIT 子句; --可选
242 | ```
243 | **使用 update 时要注意添加 where 条件,否则将会将所有的行按照语句修改**
244 |
245 | ```sql
246 | -- 修改所有的注册时间
247 | UPDATE product
248 | SET regist_date = '2009-10-10';
249 | -- 仅修改部分商品的单价
250 | UPDATE product
251 | SET sale_price = sale_price * 10
252 | WHERE product_type = '厨房用具';
253 | ```
254 | 使用 UPDATE 也可以将列更新为 NULL(该更新俗称为NULL清空)。此时只需要将赋值表达式右边的值直接写为 NULL 即可。
255 |
256 | ```sql
257 | -- 将商品编号为0008的数据(圆珠笔)的登记日期更新为NULL
258 | UPDATE product
259 | SET regist_date = NULL
260 | WHERE product_id = '0008';
261 | ```
262 | 和 INSERT 语句一样, UPDATE 语句也可以将 NULL 作为一个值来使用。
263 | **但是,只有未设置 NOT NULL 约束和主键约束的列才可以清空为NULL。**如果将设置了上述约束的列更新为 NULL,就会出错,这点与INSERT 语句相同。
264 |
265 | 多列更新
266 |
267 | UPDATE 语句的 SET 子句支持同时将多个列作为更新对象。
268 |
269 | ```sql
270 | -- 基础写法,一条UPDATE语句只更新一列
271 | UPDATE product
272 | SET sale_price = sale_price * 10
273 | WHERE product_type = '厨房用具';
274 | UPDATE product
275 | SET purchase_price = purchase_price / 2
276 | WHERE product_type = '厨房用具';
277 | ```
278 | 该写法可以得到正确结果,但是代码较为繁琐。可以采用合并的方法来简化代码。
279 |
280 | ```sql
281 | -- 合并后的写法
282 | UPDATE product
283 | SET sale_price = sale_price * 10,
284 | purchase_price = purchase_price / 2
285 | WHERE product_type = '厨房用具';
286 | ```
287 | 需要明确的是,SET 子句中的列不仅可以是两列,还可以是三列或者更多。
288 |
289 | ### 1.2.8 向 product 表中插入数据
290 |
291 | 为了学习 `INSERT` 语句用法,我们首先创建一个名为 productins 的表,建表语句如下:
292 | ```sql
293 | CREATE TABLE productins
294 | (product_id CHAR(4) NOT NULL,
295 | product_name VARCHAR(100) NOT NULL,
296 | product_type VARCHAR(32) NOT NULL,
297 | sale_price INTEGER DEFAULT 0,
298 | purchase_price INTEGER ,
299 | regist_date DATE ,
300 | PRIMARY KEY (product_id));
301 | ```
302 |
303 | 基本语法:
304 |
305 | ```sql
306 | INSERT INTO <表名> (列1, 列2, 列3, ……) VALUES (值1, 值2, 值3, ……);
307 | ```
308 | 对表进行全列 INSERT 时,可以省略表名后的列清单。这时 VALUES子句的值会默认按照从左到右的顺序赋给每一列。
309 |
310 | ```sql
311 | -- 包含列清单
312 | INSERT INTO productins (product_id, product_name, product_type, sale_price, purchase_price, regist_date) VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
313 | -- 省略列清单
314 | INSERT INTO productins VALUES ('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
315 | ```
316 | 原则上,执行一次 INSERT 语句会插入一行数据。插入多行时,通常需要循环执行相应次数的 INSERT 语句。其实很多 RDBMS 都支持一次插入多行数据
317 |
318 | ```sql
319 | -- 通常的INSERT
320 | INSERT INTO productins VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11');
321 | INSERT INTO productins VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL);
322 | INSERT INTO productins VALUES ('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
323 | -- 多行INSERT ( DB2、SQL、SQL Server、 PostgreSQL 和 MySQL多行插入)
324 | INSERT INTO productins VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11'),
325 | ('0003', '运动T恤', '衣服', 4000, 2800, NULL),
326 | ('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
327 | -- Oracle中的多行INSERT
328 | INSERT ALL INTO productins VALUES ('0002', '打孔器', '办公用品', 500, 320, '2009-09-11')
329 | INTO productins VALUES ('0003', '运动T恤', '衣服', 4000, 2800, NULL)
330 | INTO productins VALUES ('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20')
331 | SELECT * FROM DUAL;
332 | -- DUAL是Oracle特有(安装时的必选项)的一种临时表A。因此“SELECT *FROM DUAL” 部分也只是临时性的,并没有实际意义。
333 | ```
334 | INSERT 语句中想给某一列赋予 NULL 值时,可以直接在 VALUES子句的值清单中写入 NULL。想要插入 NULL 的列一定不能设置 NOT NULL 约束。
335 |
336 | ```sql
337 | INSERT INTO productins (product_id, product_name, product_type, sale_price, purchase_price, regist_date) VALUES ('0006', '叉子', '厨房用具', 500, NULL, '2009-09-20');
338 | ```
339 | 还可以向表中插入默认值(初始值)。可以通过在创建表的CREATE TABLE 语句中设置DEFAULT约束来设定默认值。
340 |
341 | ```sql
342 | CREATE TABLE productins
343 | (product_id CHAR(4) NOT NULL,
344 | (略)
345 | sale_price INTEGER
346 | (略) DEFAULT 0, -- 销售单价的默认值设定为0;
347 | PRIMARY KEY (product_id));
348 | ```
349 | 可以使用INSERT … SELECT 语句从其他表复制数据。
350 | ```sql
351 | -- 将商品表中的数据复制到商品复制表中
352 | INSERT INTO productcopy (product_id, product_name, product_type, sale_price, purchase_price, regist_date)
353 | SELECT product_id, product_name, product_type, sale_price, purchase_price, regist_date
354 | FROM Product;
355 | ```
356 | * 本课程用表插入数据sql如下:
357 | ```sql
358 | - DML :插入数据
359 | STARTTRANSACTION;
360 | INSERT INTO product VALUES('0001', 'T恤衫', '衣服', 1000, 500, '2009-09-20');
361 | INSERT INTO product VALUES('0002', '打孔器', '办公用品', 500, 320, '2009-09-11');
362 | INSERT INTO product VALUES('0003', '运动T恤', '衣服', 4000, 2800, NULL);
363 | INSERT INTO product VALUES('0004', '菜刀', '厨房用具', 3000, 2800, '2009-09-20');
364 | INSERT INTO product VALUES('0005', '高压锅', '厨房用具', 6800, 5000, '2009-01-15');
365 | INSERT INTO product VALUES('0006', '叉子', '厨房用具', 500, NULL, '2009-09-20');
366 | INSERT INTO product VALUES('0007', '擦菜板', '厨房用具', 880, 790, '2008-04-28');
367 | INSERT INTO product VALUES('0008', '圆珠笔', '办公用品', 100, NULL, '2009-11-11');
368 | COMMIT;
369 | ```
370 |
371 | # 练习题
372 |
373 | ## 1.1
374 |
375 | 编写一条 CREATE TABLE 语句,用来创建一个包含表 1-A 中所列各项的表 Addressbook (地址簿),并为 regist_no (注册编号)列设置主键约束
376 |
377 | 表1-A 表 Addressbook (地址簿)中的列
378 |
379 | 
380 |
381 |
382 | ## 1.2
383 |
384 | 假设在创建练习1.1中的 Addressbook 表时忘记添加如下一列 postal_code (邮政编码)了,请把此列添加到 Addressbook 表中。
385 |
386 | 列名 : postal_code
387 |
388 | 数据类型 :定长字符串类型(长度为 8)
389 |
390 | 约束 :不能为 NULL
391 |
392 |
393 |
394 | ## 1.3
395 |
396 | 编写 SQL 语句来删除 Addressbook 表。
397 |
398 | ## 1.4
399 |
400 | 编写 SQL 语句来恢复删除掉的 Addressbook 表。
401 |
--------------------------------------------------------------------------------
/Task02:基础查询与排序.md:
--------------------------------------------------------------------------------
1 | # 2.1 SELECT语句基础
2 |
3 | ## 2.1.1 从表中选取数据
4 |
5 | ### SELECT语句
6 |
7 | 从表中选取数据时需要使用SELECT语句,也就是只从表中选出(SELECT)必要数据的意思。通过SELECT语句查询并选取出必要数据的过程称为匹配查询或查询(query)。
8 |
9 | 基本SELECT语句包含了SELECT和FROM两个子句(clause)。示例如下:
10 |
11 | ```sql
12 | SELECT <列名>,
13 | FROM <表名>;
14 | ```
15 | 其中,SELECT子句中列举了希望从表中查询出的列的名称,而FROM子句则指定了选取出数据的表的名称。
16 | ## 2.1.2 从表中选取符合条件的数据
17 |
18 | ### WHERE语句
19 |
20 | 当不需要取出全部数据,而是选取出满足“商品种类为衣服”“销售单价在1000日元以上”等某些条件的数据时,使用WHERE语句。
21 |
22 | SELECT 语句通过WHERE子句来指定查询数据的条件。在WHERE 子句中可以指定“某一列的值和这个字符串相等”或者“某一列的值大于这个数字”等条件。执行含有这些条件的SELECT语句,就可以查询出只符合该条件的记录了。
23 |
24 | ```sql
25 | SELECT <列名>, ……
26 | FROM <表名>
27 | WHERE <条件表达式>;
28 | ```
29 | 比较下面两者输出结果的不同:
30 | ```sql
31 | -- 用来选取product type列为衣服’的记录的SELECT语句
32 | SELECT product_name, product_type
33 | FROM product
34 | WHERE product_type = '衣服';
35 | -- 也可以选取出不是查询条件的列(条件列与输出列不同)
36 | SELECT product_name
37 | FROM product
38 | WHERE product_type = '衣服';
39 | ```
40 | ##
41 | ## 2.1.3 相关法则
42 |
43 | * 星号(*)代表全部列的意思。
44 | * SQL中可以随意使用换行符,不影响语句执行(但不可插入空行)。
45 | * 设定汉语别名时需要使用双引号(")括起来。
46 | * 在SELECT语句中使用DISTINCT可以删除重复行。
47 | * 注释是SQL语句中用来标识说明或者注意事项的部分。分为1行注释"-- "和多行注释两种"/* */"。
48 | ```sql
49 | -- 想要查询出全部列时,可以使用代表所有列的星号(*)。
50 | SELECT *
51 | FROM <表名>;
52 | -- SQL语句可以使用AS关键字为列设定别名(用中文时需要双引号(“”))。
53 | SELECT product_id As id,
54 | product_name As name,
55 | purchase_price AS "进货单价"
56 | FROM product;
57 | -- 使用DISTINCT删除product_type列中重复的数据
58 | SELECT DISTINCT product_type
59 | FROM product;
60 | ```
61 | #
62 | # 2.2 算术运算符和比较运算符
63 |
64 | ## 2.2.1 算术运算符
65 |
66 | SQL语句中可以使用的四则运算的主要运算符如下:
67 |
68 | |含义|运算符|
69 | |:----|:----|
70 | |加法|+|
71 | |减法|-|
72 | |乘法|*|
73 | |除法|/|
74 |
75 | ##
76 | ## 2.2.2 比较运算符
77 |
78 | ```sql
79 | -- 选取出sale_price列为500的记录
80 | SELECT product_name, product_type
81 | FROM product
82 | WHERE sale_price = 500;
83 | ```
84 | SQL常见比较运算符如下:
85 | |运算符|含义|
86 | |:----|:----|
87 | |=|和~相等|
88 | |<>|和~不相等|
89 | |>=|大于等于~|
90 | |>|大于~|
91 | |<=|小于等于~|
92 | |<|小于~|
93 |
94 | ##
95 | ## 2.2.3 常用法则
96 |
97 | * SELECT子句中可以使用常数或者表达式。
98 | * 使用比较运算符时一定要注意不等号和等号的位置。
99 | * 字符串类型的数据原则上按照字典顺序进行排序,不能与数字的大小顺序混淆。
100 | * 希望选取NULL记录时,需要在条件表达式中使用IS NULL运算符。希望选取不是NULL的记录时,需要在条件表达式中使用IS NOT NULL运算符。
101 |
102 | 相关代码如下:
103 |
104 | ```sql
105 | -- SQL语句中也可以使用运算表达式
106 | SELECT product_name, sale_price, sale_price * 2 AS "sale_price x2"
107 | FROM product;
108 | -- WHERE子句的条件表达式中也可以使用计算表达式
109 | SELECT product_name, sale_price, purchase_price
110 | FROM product
111 | WHERE sale_price-purchase_price >= 500;
112 | /* 对字符串使用不等号
113 | 首先创建chars并插入数据
114 | 选取出大于‘2’的SELECT语句*/
115 | -- DDL:创建表
116 | CREATE TABLE chars
117 | (chr CHAR(3)NOT NULL,
118 | PRIMARY KEY(chr));
119 | -- 选取出大于'2'的数据的SELECT语句('2'为字符串)
120 | SELECT chr
121 | FROM chars
122 | WHERE chr > '2';
123 | -- 选取NULL的记录
124 | SELECT product_name, purchase_price
125 | FROM product
126 | WHERE purchase_price IS NULL;
127 | -- 选取不为NULL的记录
128 | SELECT product_name, purchase_price
129 | FROM product
130 | WHERE purchase_price IS NOT NULL;
131 | ```
132 | #
133 | # 2.3 逻辑运算符
134 |
135 | ## 2.3.1 NOT运算符
136 |
137 | 想要表示“不是……”时,除了前文的<>运算符外,还存在另外一个表示否定、使用范围更广的运算符:NOT。
138 |
139 | NOT不能单独使用,如下例:
140 |
141 | ```sql
142 | -- 选取出销售单价大于等于1000日元的记录
143 | SELECT product_name, product_type, sale_price
144 | FROM product
145 | WHERE sale_price >= 1000;
146 | -- 向代码清单2-30的查询条件中添加NOT运算符
147 | SELECT product_name, product_type, sale_price
148 | FROM product
149 | WHERE NOT sale_price >= 1000;
150 | ```
151 | ##
152 | ## 2.3.2 AND运算符和OR运算符
153 |
154 | 当希望同时使用多个查询条件时,可以使用AND或者OR运算符。
155 |
156 | AND 相当于“并且”,类似数学中的取交集;
157 |
158 | OR 相当于“或者”,类似数学中的取并集。
159 |
160 | 如下图所示:
161 |
162 | AND运算符工作效果图
163 |
164 | 
165 |
166 | OR运算符工作效果图
167 |
168 | 
169 |
170 | ### 通过括号优先处理
171 |
172 | 如果要查找这样一个商品,该怎么处理?
173 |
174 | >“商品种类为办公用品”并且“登记日期是 2009 年 9 月 11 日或者 2009 年 9 月 20 日”
175 | >理想结果为“打孔器”,但当你输入以下信息时,会得到错误结果
176 | ```sql
177 | -- 将查询条件原封不动地写入条件表达式,会得到错误结果
178 | SELECT product_name, product_type, regist_date
179 | FROM product
180 | WHERE product_type = '办公用品'
181 | AND regist_date = '2009-09-11'
182 | OR regist_date = '2009-09-20';
183 | ```
184 | 错误的原因是**是 AND 运算符优先于 OR 运算符**,想要优先执行OR运算,可以使用**括号**:
185 | ```sql
186 | -- 通过使用括号让OR运算符先于AND运算符执行
187 | SELECT product_name, product_type, regist_date
188 | FROM product
189 | WHERE product_type = '办公用品'
190 | AND ( regist_date = '2009-09-11'
191 | OR regist_date = '2009-09-20');
192 | ```
193 | ##
194 | ## 2.3.3 真值表
195 |
196 | 复杂运算时该怎样理解?
197 |
198 | 当碰到条件较复杂的语句时,理解语句含义并不容易,这时可以采用**真值表**来梳理逻辑关系。
199 |
200 | 什么是真值?
201 |
202 | 本节介绍的三个运算符 NOT、AND 和 OR 称为逻辑运算符。这里所说的逻辑就是对真值进行操作的意思。**真值**就是值为真(TRUE)或假 (FALSE)其中之一的值。
203 |
204 | 例如,对于 sale_price >= 3000 这个查询条件来说,由于 product_name 列为 '运动 T 恤' 的记录的 sale_price 列的值是 2800,因此会返回假(FALSE),而 product_name 列为 '高压锅' 的记录的sale_price 列的值是 5000,所以返回真(TRUE)。
205 |
206 | **AND 运算符**两侧的真值都为真时返回真,除此之外都返回假。
207 |
208 | **OR 运算符**两侧的真值只要有一个不为假就返回真,只有当其两侧的真值都为假时才返回假。
209 |
210 | **NOT运算符**只是单纯的将真转换为假,将假转换为真。
211 |
212 | 真值表
213 |
214 | 
215 |
216 | 查询条件为P AND(Q OR R)的真值表
217 |
218 | 
219 |
220 | ### 含有NULL时的真值
221 |
222 | NULL的真值结果既不为真,也不为假,因为并不知道这样一个值。
223 |
224 | 那该如何表示呢?
225 |
226 | 这时真值是除真假之外的第三种值——**不确定**(UNKNOWN)。一般的逻辑运算并不存在这第三种值。SQL 之外的语言也基本上只使用真和假这两种真值。与通常的逻辑运算被称为二值逻辑相对,只有 SQL 中的逻辑运算被称为三值逻辑。
227 |
228 | 三值逻辑下的AND和OR真值表为:
229 |
230 | 
231 |
232 | ##
233 | ## 练习题-第一部分
234 |
235 | ### 2.1
236 |
237 | 编写一条SQL语句,从product(商品)表中选取出“登记日期(regist在2009年4月28日之后”的商品,查询结果要包含product name和regist_date两列。
238 |
239 | ###
240 | ### 2.2
241 |
242 | 请说出对product 表执行如下3条SELECT语句时的返回结果。
243 |
244 | ①
245 |
246 | ```sql
247 | SELECT *
248 | FROM product
249 | WHERE purchase_price = NULL;
250 | ```
251 | ②
252 | ```sql
253 | SELECT *
254 | FROM product
255 | WHERE purchase_price <> NULL;
256 | ```
257 | ③
258 | ```sql
259 | SELECT *
260 | FROM product
261 | WHERE product_name > NULL;
262 | ```
263 | ###
264 | ### 2.3
265 |
266 | 代码清单2-22(2-2节)中的SELECT语句能够从product表中取出“销售单价(saleprice)比进货单价(purchase price)高出500日元以上”的商品。请写出两条可以得到相同结果的SELECT语句。执行结果如下所示。
267 |
268 | ```sql
269 | product_name | sale_price | purchase_price
270 | -------------+------------+------------
271 | T恤衫 | 1000 | 500
272 | 运动T恤 | 4000 | 2800
273 | 高压锅 | 6800 | 5000
274 | ```
275 | ###
276 | ### 2.4
277 |
278 | 请写出一条SELECT语句,从product表中选取出满足“销售单价打九折之后利润高于100日元的办公用品和厨房用具”条件的记录。查询结果要包括product_name列、product_type列以及销售单价打九折之后的利润(别名设定为profit)。
279 |
280 | 提示:销售单价打九折,可以通过saleprice列的值乘以0.9获得,利润可以通过该值减去purchase_price列的值获得。
281 |
282 | # 2.4 对表进行聚合查询
283 |
284 | ## 2.4.1 聚合函数
285 |
286 | SQL中用于汇总的函数叫做聚合函数。以下五个是最常用的聚合函数:
287 |
288 | * COUNT:计算表中的记录数(行数)
289 | * SUM:计算表中数值列中数据的合计值
290 | * AVG:计算表中数值列中数据的平均值
291 | * MAX:求出表中任意列中数据的最大值
292 | * MIN:求出表中任意列中数据的最小值
293 |
294 | 请沿用第一章的数据,使用以下操作熟练函数:
295 |
296 | ```sql
297 | -- 计算全部数据的行数(包含NULL)
298 | SELECT COUNT(*)
299 | FROM product;
300 | -- 计算NULL以外数据的行数
301 | SELECT COUNT(purchase_price)
302 | FROM product;
303 | -- 计算销售单价和进货单价的合计值
304 | SELECT SUM(sale_price), SUM(purchase_price)
305 | FROM product;
306 | -- 计算销售单价和进货单价的平均值
307 | SELECT AVG(sale_price), AVG(purchase_price)
308 | FROM product;
309 | -- MAX和MIN也可用于非数值型数据
310 | SELECT MAX(regist_date), MIN(regist_date)
311 | FROM product;
312 | ```
313 | ###
314 | ### 使用聚合函数删除重复值
315 |
316 | ```sql
317 | -- 计算去除重复数据后的数据行数
318 | SELECT COUNT(DISTINCT product_type)
319 | FROM product;
320 | -- 是否使用DISTINCT时的动作差异(SUM函数)
321 | SELECT SUM(sale_price), SUM(DISTINCT sale_price)
322 | FROM product;
323 | ```
324 | ##
325 | ## 2.4.2 常用法则
326 |
327 | * COUNT函数的结果根据参数的不同而不同。COUNT(*)会得到包含NULL的数据行数,而COUNT(<列名>)会得到NULL之外的数据行数。
328 | * 聚合函数会将NULL排除在外。但COUNT(*)例外,并不会排除NULL。
329 | * MAX/MIN函数几乎适用于所有数据类型的列。SUM/AVG函数只适用于数值类型的列。
330 | * 想要计算值的种类时,可以在COUNT函数的参数中使用DISTINCT。
331 | * 在聚合函数的参数中使用DISTINCT,可以删除重复数据。
332 | #
333 | # 2.5 对表进行分组
334 |
335 | ## 2.5.1 GROUP BY语句
336 |
337 | 之前使用聚合函数都是会整个表的数据进行处理,当你想将进行分组汇总时(即:将现有的数据按照某列来汇总统计),GROUP BY可以帮助你:
338 |
339 | ```sql
340 | SELECT <列名1>,<列名2>, <列名3>, ……
341 | FROM <表名>
342 | GROUP BY <列名1>, <列名2>, <列名3>, ……;
343 | ```
344 | 看一看是否使用GROUP BY语句的差异:
345 | ```sql
346 | -- 按照商品种类统计数据行数
347 | SELECT product_type, COUNT(*)
348 | FROM product
349 | GROUP BY product_type;
350 | -- 不含GROUP BY
351 | SELECT product_type, COUNT(*)
352 | FROM product
353 | ```
354 | 按照商品种类对表进行切分
355 |
356 | 
357 |
358 | 这样,GROUP BY 子句就像切蛋糕那样将表进行了分组。在 GROUP BY 子句中指定的列称为**聚合键**或者**分组列**。
359 |
360 | ###
361 | ### 聚合键中包含NULL时
362 |
363 | 将进货单价(purchase_price)作为聚合键举例:
364 |
365 | ```sql
366 | SELECT purchase_price, COUNT(*)
367 | FROM product
368 | GROUP BY purchase_price;
369 | ```
370 | 此时会将NULL作为一组特殊数据进行处理
371 | ###
372 | ### GROUP BY书写位置
373 |
374 | GROUP BY的子句书写顺序有严格要求,不按要求会导致SQL无法正常执行,目前出现过的子句顺序为:
375 |
376 | 1 SELECT → 2. FROM → 3. WHERE → 4. GROUP BY
377 |
378 | 其中前三项用于筛选数据,GROUP BY对筛选出的数据进行处理
379 |
380 | ###
381 | ### 在WHERE子句中使用GROUP BY
382 |
383 | ```sql
384 | SELECT purchase_price, COUNT(*)
385 | FROM product
386 | WHERE product_type = '衣服'
387 | GROUP BY purchase_price;
388 | ```
389 | ##
390 | ## 2.5.2 常见错误
391 |
392 | 在使用聚合函数及GROUP BY子句时,经常出现的错误有:
393 |
394 | 1. 在聚合函数的SELECT子句中写了聚合健以外的列 使用COUNT等聚合函数时,SELECT子句中如果出现列名,只能是GROUP BY子句中指定的列名(也就是聚合键)。
395 | 2. 在GROUP BY子句中使用列的别名 SELECT子句中可以通过AS来指定别名,但在GROUP BY中不能使用别名。因为在DBMS中 ,SELECT子句在GROUP BY子句后执行。
396 | 3. 在WHERE中使用聚合函数 原因是聚合函数的使用前提是结果集已经确定,而WHERE还处于确定结果集的过程中,所以相互矛盾会引发错误。 如果想指定条件,可以在SELECT,HAVING(下面马上会讲)以及ORDER BY子句中使用聚合函数。
397 | #
398 | # 2.6 为聚合结果指定条件
399 |
400 | ## 2.6.1 用HAVING得到特定分组
401 |
402 | 将表使用GROUP BY分组后,怎样才能只取出其中两组?
403 |
404 | 
405 |
406 | 这里WHERE不可行,因为,WHERE子句只能指定记录(行)的条件,而不能用来指定组的条件(例如,“数据行数为 2 行”或者“平均值为 500”等)。
407 |
408 | 可以在GROUP BY后使用HAVING子句。
409 |
410 | HAVING的用法类似WHERE
411 |
412 | ##
413 | ## 2.6.2 HAVING特点
414 |
415 | HAVING子句用于对分组进行过滤,可以使用数字、聚合函数和GROUP BY中指定的列名(聚合键)。
416 |
417 | ```sql
418 | -- 数字
419 | SELECT product_type, COUNT(*)
420 | FROM product
421 | GROUP BY product_type
422 | HAVING COUNT(*) = 2;
423 | -- 错误形式(因为product_name不包含在GROUP BY聚合键中)
424 | SELECT product_type, COUNT(*)
425 | FROM product
426 | GROUP BY product_type
427 | HAVING product_name = '圆珠笔';
428 | ```
429 | #
430 | # 2.7 对查询结果进行排序
431 |
432 | ## 2.7.1 ORDER BY
433 |
434 | SQL中的执行结果是随机排列的,当需要按照特定顺序排序时,可已使用**ORDER BY**子句。
435 |
436 | ```sql
437 | SELECT <列名1>, <列名2>, <列名3>, ……
438 | FROM <表名>
439 | ORDER BY <排序基准列1>, <排序基准列2>, ……
440 | ```
441 | 默认为升序排列,降序排列为DESC
442 | ```sql
443 | -- 降序排列
444 | SELECT product_id, product_name, sale_price, purchase_price
445 | FROM product
446 | ORDER BY sale_price DESC;
447 | -- 多个排序键
448 | SELECT product_id, product_name, sale_price, purchase_price
449 | FROM product
450 | ORDER BY sale_price, product_id;
451 | -- 当用于排序的列名中含有NULL时,NULL会在开头或末尾进行汇总。
452 | SELECT product_id, product_name, sale_price, purchase_price
453 | FROM product
454 | ORDER BY purchase_price;
455 | ```
456 | ##
457 | ## 2.7.2 ORDER BY中列名可使用别名
458 |
459 | 前文讲GROUP BY中提到,GROUP BY 子句中不能使用SELECT 子句中定义的别名,但是在 ORDER BY 子句中却可以使用别名。为什么在GROUP BY中不可以而在ORDER BY中可以呢?
460 |
461 | 这是因为SQL在使用 HAVING 子句时 SELECT 语句的顺序为:
462 |
463 | FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。
464 |
465 | 其中SELECT的执行顺序在 GROUP BY 子句之后,ORDER BY 子句之前。也就是说,当在ORDER BY中使用别名时,已经知道了SELECT设置的别名存在,但是在GROUP BY中使用别名时还不知道别名的存在,所以不能在ORDER BY中可以使用别名,但是在GROUP BY中不能使用别名
466 |
467 | ##
468 | ## 练习题-第二部分
469 |
470 | ### 2.5
471 |
472 | 请指出下述SELECT语句中所有的语法错误。
473 |
474 | ```sql
475 | SELECT product_id, SUM(product_name)
476 | --本SELECT语句中存在错误。
477 | FROM product
478 | GROUP BY product_type
479 | WHERE regist_date > '2009-09-01';
480 | ```
481 | ### 2.6
482 |
483 | 请编写一条SELECT语句,求出销售单价( `sale_price` 列)合计值大于进货单价( `purchase_price` 列)合计值1.5倍的商品种类。执行结果如下所示。
484 |
485 | ```sql
486 | product_type | sum | sum
487 | -------------+------+------
488 | 衣服 | 5000 | 3300
489 | 办公用品 | 600 | 320
490 | ```
491 | 
492 |
493 | ### 2.7
494 |
495 | 此前我们曾经使用SELECT语句选取出了product(商品)表中的全部记录。当时我们使用了ORDERBY子句来指定排列顺序,但现在已经无法记起当时如何指定的了。请根据下列执行结果,思考ORDERBY子句的内容。
496 |
497 | 
498 |
499 |
--------------------------------------------------------------------------------
/Task03:复杂一点的查询.md:
--------------------------------------------------------------------------------
1 | 之前接触了sql基本的查询用法,接下来介绍一些相对复杂的用法。
2 |
3 | # 3.1 视图
4 |
5 | 我们先来看一个查询语句
6 |
7 | ```sql
8 | SELECT stu_name FROM view_students_info;
9 | ```
10 | 单从表面上看起来这个语句是和正常的从数据表中查询数据是完全相同的,但其实我们操作的是一个视图。所以从SQL的角度来说操作视图与操作表看起来是完全相同的,那么为什么还会有视图的存在呢?视图到底是什么?视图与表有什么不同呢?
11 | ## 3.1.1 什么是视图
12 |
13 | 视图是一个虚拟的表,不同于直接操作数据表,视图是依据SELECT语句来创建的(会在下面具体介绍),所以操作视图时会根据创建视图的SELECT语句生成一张虚拟表,然后在这张虚拟表上做SQL操作。
14 |
15 | ## 3.1.2 视图与表有什么区别
16 |
17 | 《*sql**基础**教程**第2版*》用一句话非常凝练的概括了视图与表的区别---“是否保存了实际的数据”。所以视图并不是数据库真实存储的数据表,它可以看作是一个窗口,通过这个窗口我们可以看到数据库表中真实存在的数据。所以我们要区别视图和数据表的本质,即视图是基于真实表的一张虚拟的表,其数据来源均建立在真实表的基础上。
18 |
19 | 
20 |
21 | *图片来源:《sql基础教程第2版》*
22 |
23 | 下面这句顺口溜也方便大家记忆视图与表的关系:“视图不是表,视图是虚表,视图依赖于表”。
24 |
25 | ## 3.1.3 为什么会存在视图
26 |
27 | 那既然已经有数据表了,为什么还需要视图呢?主要有以下几点原因:
28 |
29 | 1. 通过定义视图可以将频繁使用的SELECT语句保存以提高效率。
30 | 2. 通过定义视图可以使用户看到的数据更加清晰。
31 | 3. 通过定义视图可以不对外公开数据表全部字段,增强数据的保密性。
32 | 4. 通过定义视图可以降低数据的冗余。
33 | ## 3.1.4 如何创建视图
34 |
35 | 说了这么多视图与表的区别,下面我们就一起来看一下如何创建视图吧。
36 |
37 | 创建视图的基本语法如下:
38 |
39 | ```sql
40 | CREATE VIEW <视图名称>(<列名1>,<列名2>,...) AS