一、MySQL
1、MySQL 表数据的增、删、查、改
-
MySQL 中表数据的操作本质:一般先将磁盘数据传输给内存,内存得到的数据在和磁盘的数据进行映射关联,经过一系列过滤操作,被过滤的数据删除掉是不和磁盘同步的,留下过滤后的数据再进行合并,用户再对这些数据操作,过滤后剩下的数据增/删/改操作要和磁盘数据同步,这样就间接操作磁盘的数据了
-
内存过滤语句:
select 子句、where子句、order by子句、limit子句、group by子句、having 子句- 内存过滤语句:过滤,而
select子句是过滤,group by子句是过滤掉整个老表后内存中产生新表,where子句是老表的条件筛选、having子句是新表的条件筛选
- 内存过滤语句:过滤,而
-
内存操作语句:
insert子句、update子句、delete子句- 内存操作语句:操作+内存磁盘同步数据
-
内存过滤语句执行完后,是不回合磁盘数据同步的,内存操作语句执行完后,都会和磁盘数据同步的
1-1、表数据的基本增加操作--CURD--C
- 语法
SQL
INSERT [INTO] table_name [(column) [,column] ...] VALUES (value_list) [,(value_list)] ...
value_list: value,[,value] ...
1-1-1、单行插入
- 单行全列插入:
insert into 表 values (字段1数据,...); - 单行指定列插入:
insert into 表 (字段1名,...) values (字段1数据,...);
1-1-2、多行插入
- 多行全列插入:
insert into 表 values (字段1数据1,...),(字段1数据2,...),...; - 多行指定列插入:
insert into 表 (字段1名,...,字段n名) values (字段1数据,...,字段n数据),(字段1数据,...,字段n数据),...;
1-1-3、主键或唯一键修饰字段数据,表中没重复则插入,重复则更新
- 语法 1
- 原理:直接原地更新老数据,不会自增主键
SQL
INSERT ... ON DUPLICATE KEY UPDATE column = value [,column = value] ...
- 语法 2
- 原理:删除冲突老数据,重新插入新数据,会自增主键
SQL
REPLACE INTO 表名 (字段1名,...) VALUES (字段1数据,...)
1-2、表数据的基本查询操作--CURD--R
- 表数据的查询经常使用--重点
- 原理:mysqld 会先根据
from [指定表]把表中全部数据拿出,根据where [行筛选]筛选出行后,可执行group by进行分组后,紧接着必须使用聚合函数构成新表后,再交给select [列投影] from投影出列,然后使用having子句行筛选,之后order by [排序条件]排个序,最后limit [分页条件]行筛选出最终结果交给用户- mysqld 拿出表中全部数据后,先
where条件筛选行,再投影列,然后排个序,最后limit筛选行
- mysqld 拿出表中全部数据后,先
- 语法
SQL
SELECT [DISTINCT] {* | {collumn [,column] ...}} [FROM table_name] [WHERE ...] [group by 条件 [having 条件] ] [ORDER BY column [ASC | DESC], ...] LIMIT ...
1-2-1、全列查询
- 通过通配符
*进行全列查询 select * from table_name;
1-2-2、指定列查询
select 指定字段1 [, 指定字段2] ... from table_name;
1-2-3、搭配表达式查询
- select 不仅可以用于查询,后面跟表达式和函数,select 后面跟表达式/函数的计算是在内存中的计算,并且色 select 是过滤语句不会影响同步到磁盘数据的
select [表达式/函数]
- 查询后将
结果表的列名进行重命名,重命名后显示给用户,注意列重命名只能在列投影时或者列投影操作之后进行重命名select [列/表达式/函数] as [重命名] from table_name;
- 根据指定列的数据去重后显示给用户
select distinct [列/表达式/函数] from table_name;
1-2-4、WHERE 行筛选--条件筛选
- where 子句是行筛选中的条件筛选,其是行筛选也是条件筛选
- 把全部数据拿出后,再根据 where 语句后的条件,进行指定行筛选,然后交给列投影,投影完成后显示给用户
- where 子句后面可以使用 比较运算符 和 逻辑运算符
1-2-5、结果排序
- 结果排序本质:在磁盘物理中并未排序,mysqld 会把磁盘的数据放到内存中,然后进行磁盘和内存的数据进行映射,经过一些列过滤数据操作,过滤掉的数据在内存中清除掉不和磁盘数据同步,只在内存留下过滤后的数据,把内存的这些数据进行排序,这样我们就可以根据内存排好序的数据,思路清晰的修改内存数据,内存又会根据映射把未排序的磁盘数据进行数据同步,这样就可以完美的修改磁盘中的数据了
结果排序完成后内存和磁盘逻辑图
bash
_______________
_V__ |
| b | ____V____
| a<-|-------|->a b c |(内存)
| c | |______^__|
|_^__|(磁盘) |
|________________/
- 语法
SQL
-- ASC 升序
-- DESC 降序
-- mysqld 默认升序
SELECT ... FROM table_name [WHERE ...] ORDER BY column [ASC|DESC], [...];
ORDER BY column1 [ASC|DESC] column2 [ASC|DESC],...columnn[ASC|DESC]- 在满足 column1 排序的基础上再排序 column2 以此类推,依次在满足上一个排序的基础上进行排序
- 知识点补充:SQL 语句中
--是单行注释的意思
1-2-6、分页操作--行筛选
limit [指定开始读的位置],[开始位置连续向下读几行]- 起始行下标为 0
- 分页操作是行筛选,但不是条件筛选
1-3、表数据更新操作--CURD-U
update的原理:先进行where子句行筛选,然后交给order by排个序,排完再limit行筛选,最后把limit筛选的数据交给set更新这些行的列数据- 语法
SQL
UPDATE table_name SET column = expr [,column=expr ...] [WHERE ...] [ORDER BY ...] [LIMIT ...]
1-4、表数据的删除--CURD-D
delete的原理:先进行where子句行筛选,然后交给order by排个序,排完再limit行筛选,最后把limit筛选的数据交给delete删除这些数据所在行的全部数据- 语法
SQL
DELETE FROM table_name [WHERE ...] [ORDER BY ...] [LIMIT]
1-4-1、删除整表数据--截断表
- 截断表也是删除表的数据的一种方式,但此方式删除数据后不支持回滚,主键自增值也会归 1
- 回滚操作就是可以反悔,根据 log 日志文件,撤回当前步骤
- 语法:
TRUNCATE [TABLE] table_name->只能删除整张表
1-5、SQL 复合语句
1-5-1、查询插入复合 SQL 语句--查询结果插入表中
-
拿着查询后的数据插入在其他表
- insert 语句支持将同结构其他表的数据,查询后的结果对应磁盘的每行数据 会插入到当前表里
-
语法:
INSERT INTO table_name [(column [, column ...])] SELECT ... -
知识点补充:当创建一个新表时,新表需要的内部结构和旧表结果一模一样,则使用
create table [新表] like [旧表]即可创建出这种空的同结构新表
1-6、表数据的高级查询--分组聚合
1-6-1、聚合函数
- 聚合函数是对条件筛选且分组后,以每组为单位,对组里的行的
个数和行内数据合起来统一处理的函数,select里的表达式是只针对每行操作的函数并不合起来统一操作 - 聚合函数种类:
MIN(...)、MAX(...)、COUNT(...)、AVG(...)、SUM(...)
1-6-2、分组查询
- 分组的目的:方便更好更精细的聚合统计(方便分组完使用聚合函数,将每组根据函数得到的结果,聚合后显示成一张表给用户)
- 分组是根据哪一个字段进行分组的,字段数据相同的为一组
group by子句是重新根据旧表形成新表的语句having 子句是对group by产生新表在根据 select 过滤后的表条件筛选- 语法
SQL
select column1,column2, ..from table [where 条件] group by column_1, column_2, ... [having 条件]
-- 先根据column_1分组,然后再此分组基础上和column_2进行分组以此类推
分组聚合逻辑图
bash
新表
^
新表 新表 新表 (聚合)
^ ^ ^ ___|___ ...
(聚合) (聚合) (聚合) | | /
| | ___|___ (group 1) ...
__|__ ___|___ | | / | | \
| | | | (group 1) |... | ...
| | | | /| | \ | |
| | (group 1) |... | |... | ...
| | /| | \| | | |
(table) | ... | |... | |... | ...
| | \| | /| | | |
| | (group n) |... | |... | ...
| | | | \| | / | |
| | | | (group n) |... | ...
|_____| |_______| |_______| \ | | /
旧表 | 旧表 | 旧表 | (group n) ...
{分组} {分组} {分组}|_______| \
旧表 | ...
{分组}
分组聚合逻辑图逻辑图
此多叉树的每条路径都是聚合后新表的一条数据
zsh
_____________
组1{分组字段1数据1}--除了分组条件字段的字段数据---|------------|------>
/ | | |
(分组字段2) ... --除了分组条件字段的字段数据---|------------|------>
/ \ | | 聚 |
/ 组n{分组字段2数据n}--除了分组条件字段的字段数据--|------------|------>
组1{分组字段1数据1} ... 组1{分组字段2数据n}--除了分组条件字段的字段数据-|------------|------>
/ | \ / | | 合 |
/ | (分组字段2) ... --除了分组条件字段的字段数据-----|------------|-------->
/ | \ | | 函 |
/ | 组n{分组字段1数据1}--除了分组条件字段的字段数据--|------------|--------->
[表]-(分组字段1) ... ... 组1{分组字段1数据1}--除了分组条件字段的字段数据---|------------|--------->
\ | / | | 数 |
\ | (分组字段2) ... --除了分组条件字段的字段数据-----|------------|-------->
\ | / \ | | |
\ | / 组n{分组字段1数据1}--除了分组条件字段的字段数据----|-------------|-------->
组n{分组字段1数据n} ... 组1{分组字段1数据1}--除了分组条件字段的字段数据----|-------------|-------->
\ / | | |
(分组字段2) ... --除了分组条件字段的字段数据--------|-------------|--------->
\ | | |
组n{分组字段2数据n} --除了分组条件字段的字段数据--|-------------|-------->
|_____________|
- 如图所示:聚合要么直接原表聚合,要么先分组再聚合
- 新表的行数是由
group n里 n 决定的,列可以由聚合函数/分组所用的条件字段来充当
- 新表的行数是由