这篇文章主要梳理了 SQL 的基础用法,会涉及到以下方面内容:
SQL大小写的规范
数据库的类型以及适用场景
SELECT 的执行过程
WHERE 使用规范
MySQL 中常见函数
子查询分类
如何选择合适的 EXISTS 和 IN 子查询
了解 SQLSQL 是我们用来最长和数据打交道的方式之一,如果按照功能划分可分为如下 4 个部分:
DDL,数据定义语言。定义数据库对象,数据表,数据列。也就是,对数据库和表结构进行增删改操作。
DML,数据操作语言。对数据表的增删改。
DCL,数据控制语言。定义访问权限和安全级别。
DQL,数据查询语言。用来查询数据。
平时在编写 SQL 时,可能发现许多 SQL 大小写不统一,虽然不会影响 SQL 的执行结果,但保持统一的书写规范,是提高效率的关键,通常遵循如下的原则:
表名,表别名,字段名,字段别名等用小写。
SQL 保留字,函数名,绑定变量等用大写。
数据表,字段名采用下划线命名。
目前排名较前的 DBMS:
关系型数据库:建立在关系模型上的数据库,在建表时,通常先设计 ER 图表示之间的关系。
键值型数据库:以 key-value 的形式存储数据,优点是查找速度快,缺点是无法向关系型数据库一样使用如 WHERE 等的过滤条件。常见场景是作为内容缓存。
文档型数据库,在保存时以文档作为处理信息的基本单位。
搜索引擎:针对全文检索而设计。核心原理是 “倒排索引”。
列式数据库:相对于如 MySQL 等行式存储的数据库,是以列将数据存在数据库中,由于列具有相同的数据类型,所以可以更好的压缩,从而减低系统的 I/O,适用于分布式文件系统,但功能相对有限。
图形数据库,利用图的数据结构存储实体之间的关系。比如社交网络中人与人的关系,数据模型为节点和边来实现。
认识 SELECTSELECT 一般是在学习 SQL 接触的第一个关键字,基础的内容就是不提了,这里整理常用的规范:
起别名 SELECT name AS n FROM student 查询常数, 增加一列固定的常数列: SELECT \'学生信息\' as student_info, name FROM student 去重重复行 SELECT DISTINCT age FROM student需要注意的是 DISTINCT 是对后面的所有列进行去重, 下面这种情况就会对 age 和 name 的组合进行去重。
SELECT DISTINCT age,name FROM student 排序数据,ASC 代表升序,DESC 代表降序如先按照 name 排序,name 相等的情况下按照 age 排序。
SELECT DISTINCT age FROM student ORDERY BY name,age DESC 限制返回的数量 SELECT DISTINCT age FROM student ORDERY BY name DESC LIMIT 5 SELECT 的执行顺序了解了 SELECT 的执行顺序,才能更好地写出更有效率的 SQL。
对于 SELECT 顺序有两个原则:
关键字的顺序不能颠倒:
SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ...
SELECT 会按照如下顺序执行:
FROM > WHERE > GROUP BY > HAVING > SELECT的字段 > DISTINCT > ORDER BY > LIMIT SELECT DISTINCT student_id, name, count(*) as num #顺序5 FROM student JOIN class ON student.class_id = class.class_id #顺序1 WHERE age > 18 #顺序2 GROUP BY student.class_id #顺序3 HAVING num > 2 #顺序4 ORDER BY num DESC #顺序6 LIMIT 2 #顺序7在逐一分析下这个过程前,我们需要知道在上面的每一个步骤中都会产生一个虚拟表,然后将这个虚拟表作为下一个步骤中作为输入,但这一过程对我们来说是不可见的:
从 FROM 语句开始,对 student 和 class 表进行 CROSS JOIN 笛卡尔积运算,得到虚拟表 vt 1-1;
通过 ON 筛选,在 vt1-1 的基础上进行过滤然后得到表 vt 1-2;
添加外部行。如使用左连接,右连接和全连接时,就会涉及到外部行,会在 vt1-2 的基础上增加外部行,得到 vt1-3。
如果超过两张表,就会重复上面的步骤。
在拿到最终的 vt1 的表数据后,会执行 WHERE 后面的过滤阶段,得到表 vt2.
接着到 GROUP 阶段,进行分组得到 vt3.
接着到 HAVING 阶段,对分组的数据进行过滤,得到 vt4.
后面进入 SELECT 阶段,提取需要的字段,得到 vt5-1,接着通过 DISTINCT 阶段,过滤到重复的行,得到 vt5-2.
然后对指定的字段进行排序,进入 ORDER BY 阶段,得到 vt6.
最后在 LIMIT 阶段,取出指定的行,对应 vt7,也就是最后的结果。
如果涉及到函数的计算比如 sum() 等,会在 GROUP BY分组后,HAVING 分组前,进行聚集函数的计算。
涉及到表达式计算,如 age * 10 等,会在 HAVING 阶段后,SELECT 阶段前进行计算。
通过这里,就可以总结出提高 SQL 效率的第一个方法:
使用 SELECT 时指定明确的列来代替 SELECT * . 从而减少网络的传输量。
使用 WHERE 进行过滤使用 WHERE 筛选时,常有通过比较运算符,逻辑运算符,通配符三种方式。
对于比较运算符,常用的运算符如下表。