Sql 查询的5子句
char 和 varchar 的区别
char 是固定分配大小的 每个字段的大小是固定的 所以它的查询效率很高
varchar 是不分 大小 你用多少 我就给你多少 但是个 数据之前 会有一个 记录数据的 特殊数据(作用就是用来做查询的) 它的 优点就是不怎么浪费内存
对于我们使用数据库而言 一般情况下来说 增删改的语法相对来说还是比较 简单 的 因为它是固定的写法 但是对于查询 还是有点难度的 因为 它是涉及的也比较广
sql查询 模型
我们理解查询模型的时候 我们要把 select 后面的列 看成是变量 既然是变量
那么列 它就可以运算 ±*/> 等等都是可以的 然后后把我们where 条件后面的
语句 看成是条件 只要变量满足我这个条件 我就可以把它取出来, 之后对这些列进行投影 这些投影 我们还可以对这些投影继续做一些筛选操作 ,但是这些只会存在结果级中 并不会出现在原始的硬盘上面
where 和having 的区别 最主要的一条我讲 就是 having 是对结果级 操作 但是where是直接对 我们硬盘上的表 操作的 大家都知道 表也是数据 存在硬盘上的
结论就是 我们having是操作 where·的结果 在where 之后
在这里插入图片描述
where
group by
如果你 group by cat_id ,那么从语法上来说 你 select 的 列 只能是 cat_id max/min/avg/sum/count(*)
having
order by(在 where group having 后) 结果级中的(字段 按哪个) desc(降序) asc(升序) ,多个字段要求排序 直接用逗号隔开 按先后顺序排序
limit offset (跳过的行数) , N(取出的行数)
sql 之 子查询
where 子查询 能查出 最大商品的价格
把内层查询的结果 当做外层的参数
where 子查询 where列=(内行sql) ,则内行返回的也必定是单行单列
SELECT * from tb_item WHERE id=(SELECT max(id) FROM tb_item);
子查询 之from子查询
查询的结果级就是一张表的数据
内层查询的结果当成一张表 供 外层的sql再次查询
查出每个栏目下最贵的商品
select * from (select goods_id.goods_name,from goods order by cat_id asc ,goods_id desc) as temp group by cat_id
子查询之 exists
多表查询
讲集合之前 我们先讲讲集合
就是高一我们学的集合
首先 集合有啥特点 第一个就是无序性和唯一性,
集合的运算 有求交集 , 并集, 迪卡尔积(相乘)
它的意思是组合 一一组合 形成一个新的集合 而并不是 说一一相乘
不是说讲对表怎么讲集合了
其实 一张表就是一个集合
他的每一行就是一个集合的元素
2表做全相乘
从行的角度来看:就是2表的每一行,两两结合
从列的角度来看:结果集中的列就是并集(列名可以重复)
2表相乘的查询是很低的 1万*1万 就很大了 产生了新表 并没有索引 并且索引没用上
3.所以我们要用左连接
什么是左连接
语法
假设A表在左不动 ,B表在A表的右边滑动,
A表和B表通过一个关系来筛选B的行
做法:
A left join B on 条件 条件为真,则B表对应的行取出,
A left join B on 也是形成一张表 结果集 where group having order by limit 都可以使用
比全相乘的效率好14倍
左连接 右连接 内连接的区别
A left join B 等于
B right join A
三表关联 则如下:
select table a left join table b(left join table c on b.id = c.tb_id) on a.id = b_ta.id
注意 既然左右连接差不多 所以尽量左连接
内连接(inner join) 从集合的角度看 内连接 和左右连接的关系
内连接是左右连接的交集
外连接 就是 左右连接的并级 但是在mysql中不支持外连接
Union
用法:sql union sql
union 合并的是结果集
取自于2张表 通过别名 让他们的结果集的列一致
那么, 如果 取出的结果集名字不一样还是可以union
不用别名的话那就以第一个表的为准
什么情况不能用union
只要结果集的列数一致就可以了
union 后的结果集能否再排序呀?
是可以的
Sql union sql2 order by 字段
关于union的排序问题
外层语句还要对最终结果,再次排序
因此内层的语句排序就没有意义
因此内层的order by 在在执行期间就给你优化掉了
有些时候order by 可以发挥作用 在 limit 存在的时候 因为改变了结果集
union 会 去掉重复的代码
union all 不会去重了
mysql常见的函数
- 数学函数 ±*/ 绝对值这些 取随机数 randm
MYSQL小问题
日期是数据库本身的特使,也是数据库本身机制中的一个重要内容;
每一个数据库处理日期采用的机制都不一样,所以在实际开发中将日期字段定义为DATE类型的情况很少
2、分组函数不能直接使用在where关键字后
count(*)统计的是结果集的总条数,count(字段名)统计的是该字段值不为null的总条数
distinct:将查询结果中的某一个字段的重复记录去除
where 在 group by之前
having 在 group by之后
一个完整的SQL语句如下:
select
xxx
from
xxx
where
xxx
group by
xxx
having
xxx
order by
xxx
1、from 将硬盘上的表文件加载到内存
2、where 将符合条件的数据行摘取出来,生成一张临时表
3、group by 根据列中的数据种类,将当前临时表划分成若干个新的临时表
4、having 可以过滤掉group by生成的不符合条件的临时表
5、select 对当前表进行整列读取
6、order by 对select生成的临时表,进行重新排序,生成新的临时表
7、limit 对最终生成的临时表的数据行进行截取
存储引擎是MySQL特有,其他数据库没有,表的类型以及表在计算机上的存储方式。
InnoDB给MySQL的表提供了事务处理、回滚、崩溃修复能力和多版本并发控制的事务安全
index
相当于一本字典目录,提高程序的检索/查询效率,表中的每一个字段都可以添加索引
主键自动添加索引
索引和表相同,是一个对象,表示存储在硬盘文件中,索引是表的一部分,因此也存放在硬盘文件中
2、通过索引检索(提高查询效率)
创建索引的情况:
1、该字段的数据量庞大
2、该字段很少使用DML操作(索引需要维护,DML操作太多的时候,影响检索效率)
3、该字段经常出现在筛选条件where中
实际开发中根据项目需求或客户需求综合调整
Mysql的sql文件过大导入出错
sql文件过大,mysql执行时超过最大包大小,导致连接断开
1.客户端max_allowed_packet取值范围4096-2G,默认值是16M
2.客户端net_buffer_length取值范围1024-512M,默认值16K
3.服务器max_allowed_packet取值范围1024-1G,默认值是1M
4.服务器net_buffer_length取值范围1024-1M, 默认值16K
解决–sql语句查询
查看通信缓冲区的大小
show global variables like ‘max_allowed_packet’;
调整大小 20M
set global max_allowed_packet=1024102420;