[TOC]
CRUD:Create Retrieve update delete
创建数据库
CREATE DATABASE symfony DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
查询数据
基本语句
select * from <表名>;
条件查询
select * from <表名> where <条件表达式>
条件表达式
NOT
、AND
、OR
,NOT
优先级最高,其次是 AND
,最后是 OR
。加上括号可以改变优先级。
投影查询
使用SELECT *
表示查询表的所有列,使用SELECT 列1, 列2, 列3
则可以仅返回指定列。
排序
select * from <表名> where <条件表达式> order by <列名, ···>
desc
:降序 asc
:升序(默认)。
分页查询
select * from <表名> where <条件表达式> order by <列名, ···> limit <M> offset <N>
limit <M> offset <N>
可简写成 limit <M>, <N>
。从第 N 条开始,截取 M 条数据。
使用LIMIT <M> OFFSET <N>
分页时,随着N
越来越大,查询效率也会越来越低。
聚合查询
count()
:计算某一列的个数。sum()
:计算某一列的合计值,该列必须为数值类型。avg()
:计算某一列的平均值,该列必须为数值类型。max()
:计算某一列的最大值。min()
:计算某一列的最小值。
聚合查询的 WHERE
条件没有匹配到任何行,COUNT()
会返回0,而 SUM()
、AVG()
、MAX()
和 MIN()
会返回 NULL
。
分组
对于聚合查询,可以根据 group by
语句来进行分组。如下面的例子:按照班级分组select class_id, count(*) num from students group by class_id;
多表查询
select * from <表名1> <别名1> <表名2> <别名2> where <条件表达式>
多表查询是笛卡尔积,两个一万行的表就会变成1亿行,效率太低,连表尽量用连接查询。
连接查询
- 先确定主表,仍然使用
FROM <表1>
的语法; - 再确定需要连接的表,使用
INNER JOIN <表2>
的语法; - 然后确定连接条件,使用
ON <条件...>
,这里的条件是s.class_id = c.id
,表示students
表的class_id
列与classes
表的id
列相同的行需要连接; - 可选:加上
WHERE
子句、ORDER BY
等子句。
MySQL不支持全外连接,所以只能采取关键字UNION来联合左、右连接。
插入数据
insert into <表名> (字段1, 字段2, ...) values (值1, 值2, ...);
值与字段要相互对应。
例如:
insert into casbin_rules (ptype, v0, v1, v2) values ("p", "eve", "articles", "read");
更新数据
update <表名> set 字段1=值1, 字段2=值2, ... where ...;
在执行UPDATE
语句时要非常小心,最好先用SELECT
语句来测试WHERE
条件是否筛选出了期望的记录集,然后再用UPDATE
更新。
删除数据
delete from <表名> where …;`
一些小知识
- 为什么别名不能用于 where 语句?
别名是在内存中生成的,where 条件查询,只能用于从硬盘中,往内存中传输数据的过程中进行条件查询,符合条件的存入内存,不符合条件的不读取。相比较而言,having 是可以针对硬盘以及内存进行条件查询的。因此,如果对于聚合函数、别名等的条件查询,需要用 having,而不是 where。
- 关系数据库的记录集没有顺序的概念,只有查询的时候才会排序。默认不指定顺序就是order by id按主键排序
- truncate 将表所有记录都删除了,所有结构的记录都删除,不可以roll back,可以触发触发器。delete 只是删除了这一行记录,一行一行删,有记录,可以回滚roll back,被删除的id的数据虽然被删除了但还是占用着id号
- 命令行程序
mysql
实际上是MySQL客户端,真正的MySQL服务器程序是mysqld
,在后台运行。
mysql -h 10.0.1.99 -u root -p
这里-h
指定 IP 或域名,