mysql 基础知识

数据定义语言分类

类型 解释 备注
DDL 数据定义语言 创建修改库、表、视图、索引、约束等
CREATE、DROP、ALTER 等
DML 数据操作语言 数据行的增删改
INSERT 、 DELETE 、 UPDATE 等
DQL 数据查询语言 SELECT 语句
DCL 数据控制语言 安全控制,比如创建用户,给用户分配权限,回滚数据等
GRANT 、 REVOKE 、 COMMIT 、 ROLLBACK 、 SAVEPOINT 等

数据类型

类型 解释 备注
float(m, d)、double(m, d) 单精度(4字节)和双精度(8字节)的浮点数
m:整数位+小数位,d:小数位
存储时,整数位超出会报错
小数位超出会四舍五入
decimal(m, d) 浮点数可能会不精确,decimal 一定是精确的
m:整数位+小数位,d:小数位
当超出范围也会四舍五入
year、time、date
datetime、timestamp
年、时间、日期、年月日日期、时间戳
char(int)、varchar 存储字符串
char 必须指定长度(固定长度)
varcahr 可以不指定长度(可变长字符串)
如果指定长度,超出会报错
varchar 默认 255,最大65535
5.0 之后,varchar 指字符长度
text tinytext:0 <= L <= 255
text:0 <= L <= 65535
mediumtext:0 <= L <= 16777215
longtext:0 <= L<= 4294967295
longtext 最大可存大约 4 GB
blob 二进制对象,也对用了 4 种blob,长度和 text 一致 java 对应类型为 byte[]

运算符

符号 解释 备注
算术运算符 +-*/%
=<>>=<=
<==> 安全等于 = 的区别是可以和 null 做对比
效果和 IS NULL 相同
<> 不等于 != 没区别,不能和 null 做对比
IS NULLISNULL 为空运算符
IS NOT NULL 不为空运算符
LEAST 最小值运算符 SELECT LEAST(1,2,3)
GREATEST 最大值运算符
BETWEEN...AND... 范围运算符 包含临界值
IN 属于运算符
NOT IN 不属于运算符
LIKE 模糊匹配
REGEXP 正则运算符
RLIKE 判断正则是否合法

别名

-- USER_AGE 指定别名,要不要 AS 都行
SELECT USER_AGE AS AGE FROM USER;
-- 对运算结果起别名要加双引号
SELECT USER_AGE+10 "AGE" FROM USER;

去重

使用 DISTINCT,只能对行去重

排序和分页

ASC:顺序;DESC:倒叙

多列排序:先以第一个字段排序,然后根据排序的结果再次以第二个字段排序

分页:LIMIT [偏移量] 行数,偏移量公式:(pageNum-1)*pageSize。limit 2,10 从下标2开始,查10条

  • select...where … group by … having … order by … limit
  • GROUP BY 中的字段必须在 SELECT 中

连接查询

联表查询,分为两个版本:sql92 和 sql95。支持的查询方式有内连接,外连接(左右外连接),全连接(MySql 不支持标准的语法,但是有提代方案)

  • 内连接:取交集,关联字段的值在主表和从表中都有的才保留
-- sql92(用逗号关联表)
select * from emp,dept where emp.deptno=dept.deptno
-- sql99(inner join 等价于 join)
select * from emp innner join dept on emp.deptno=dept.deptno
  • 外连接:取并集,以主表为准,从表中不匹配的数据用 null 代替。MySql 不支持 sql92 外连接,也不支持 sql95 全外连接,即 MySql 只支持 sql95 的左右外连接
-- sql92 左外连接(左表为主,右边不够的补null,所以右表用+号标识)--- Mysql 不支持
select * from emp, dept where emp.deptno=dept.depetno(+)
-- sql95 左外连接(left outer join 等价于 left join)
select * from emp left outer join dept on emp.deptno=dept.deptno

-- sql92 全外连接 --- Mysql 不支持
select * from emp,dept where epm.deptno(+) = dept.dpetno(+)
-- sql95 全外连接 --- Mysql 不支持
select * from emp full outer join dept on emp.deptno=dept.deptno;
  • 联合查询:UNION,UNION ALL
    • 要联合的结果集必须一样(个数,顺序,类型),不一样也能出结果但是不准确,也不是我们预期的结果
    • UNION 会去重,UNION ALL 不会去重(意味着效率会高于 UNION)
    • MySQL 不支持 sql95 全外连接(不支持FULL JOIN),可以使用联合查询代替
  • 自然连接 和 USING(sql99新特性)
-- sql95 内连接
select * from emp innner join dept on emp.deptno=dept.deptno;
-- sql99 自然连接(效果和上面一致,自动根据两个表相同的字段去关联,不用显示指定字段)
select * from emp NATURAL join dept;
-- sql99 USING 指定字段(效果和上面一样,不用 ON 指定字段,使用 USING)
select * from emp NATURAL join dept USING(dept_code);

子查询

  • 单行子查询(单字段):子查询的结果集只有一行数据,主表和子表的某个字段值相等
-- student 表的 u_id 和 user 表的 id 相等
SELECT * FROM user WHERE ID = (
    				SELECT u_id FROM student WHERE ID = 123
				);
  • 单行子查询(多字段):子查询的结果集只有一行数据,主表和子表的多个字段值相等
-- sku.item_id 等于 spu.id,并且 sku.code = spu.code
select * from spu where (id,`code`) = (
                                        select item_id, code from sku
                                        where item_id = 1300949751678957570 and code = 'test02'
                                   	);
  • 多行子查询(多字段):主表和子表都能是多行数据(单字段直接用 in 来匹配)
-- user 表和 stu表中 code 和 name 相等的
select * from user u where EXISTS (
                                   -- 这里 select 什么不重要
                                   -- 只要能匹配上,user表中的记录就保留,跟子查询没关系
                                   select 1
                                   from stu s 
                                   where u.code = s.code and u.name = s.name
                                   );

sql 执行顺序

完整的顺序:SELECT ... FROM ... WHERE ... GROUP BY ... HAVING ... ORDER BY ... LIMIT ,执行顺序如下:

SELECT ...               -- 6,过滤查询字段(字段、别名、聚合、distinct)
FROM ...                 -- 1,确定主表
INNER JOIN ... on ...    -- 2,确定从表
WHERE ...                -- 3,根据条件过滤结果集
GROUP BY ...             -- 4,查询结果分组
HAVING ...               -- 5,根据条件过滤分组结果集
ORDER BY ...             -- 7,排序(这里才能使用别名)
LIMIT ... ;              -- 8,分页
posted @ 2023-05-17 11:01  CyrusHuang  阅读(16)  评论(0编辑  收藏  举报