MySQL
基础篇
通用语法及分类
- DDL: 数据定义语言,用来定义数据库对象(数据库、表、字段)
- DML: 数据操作语言,用来对数据库表中的数据进行增删改
- DQL: 数据查询语言,用来查询数据库中表的记录
- DCL: 数据控制语言,用来创建数据库用户、控制数据库的控制权限
DDL(数据定义语言)
数据库操作
-
查询所有数据库:
show databases; -
查询当前数据库
select database(); -
创建数据库
create database [if not exists] 数据库名; -
删除数据库
drop database [if exists] 数据库名; -
使用数据库
use 数据库名;
表操作
-
查询当前数据库的所有表
show tables; -
查询表结构
desc 表名; # 但是不会显示出来注释信息,需要查询建表语句才能显示出来 -
查询指定表的建表语句
show create table 表名; -
创建表
CREATE TABLE 表名( 字段1 字段1类型 [COMMENT 字段1注释], 字段2 字段2类型 [COMMENT 字段2注释], 字段3 字段3类型 [COMMENT 字段3注释], ... 字段n 字段n类型 [COMMENT 字段n注释] # 注意逗号 )[ COMMENT 表注释 ];create table test_age( id int comment '编号', name varchar(50) comment '姓名', age int comment '年龄', sex varchar(1) comment '性别' ) comment 'test_7';
数据类型


age tinyint unsigned # 年龄 够用范围下的无符号数
score double(4, 1) # 整体长度为4,小数长度为1
varchar(10) # 超过10个字符串大小将报错
char(10) # 即使1个字符,也会占用10个字符的存储空间 性能好
# 一个汉字占用3个字节,但是是算一个字符

修改表
-
添加字段
alter table 表名 add 字段名 类型(长度) [comment 注释] [约束]; -
修改数据类型
alter table 表名 modify 字段名 新数据类型(长度); -
删除字段
alter table 表名 drop 字段名; -
修改表名
alter table 表名 rename to 新表名; -
删除表
drop table 表名; -
删除表,并重新创建该表
truncate table 表名;
DML(数据操作语言)
添加数据
-
指定字段添加数据
insert into 表名 (字段名1, 字段名2...) values (值1, 值2...); -
全部字段
insert into 表名 values (值1, 值2...); -
批量添加数据
insert into 表名 (字段名1, 字段名2...) values (值1, 值2...),(值1, 值2...)...(值1, 值2...); insert into 表名 values (值1, 值2...),(值1, 值2...)...;
修改数据
-
修改数据
update 表名 set 字段名1 = 值1, 字段名2 = 值2, ... [ where 条件 ]; # 没有where条件时就是修改表内所有的数据 update test set name = 'ucas' where id = 1; -
删除表中数据
drop table 是删除整张表(结构和数据)
delete from 表名 [where 条件]; # 没有条件就是删除所有数据 # delete不能删除某一个字段的值(可以使用update更新某个字段的值为NULL)
DQL(数据查询语言)
select
字段列表
from
表名字段
where
条件列表
group by
分组字段列表
having
分组后的条件列表
order by
排序字段列表
limit
分页参数

基础查询
-
查询字段
select 字段1, 字段2, ... from 表名; # *为全部字段,但是在开发中尽量不要使用 -
设置显示别名
select 字段1 as '地址' from 表名; # as可以省略 -
去除重复记录
select distinct 字段1 from 表名;
条件查询
select 字段 from 表名 where 条件列表;
| 比较运算符 | 功能 |
|---|---|
| > | 大于 |
| >= | 大于等于 |
| < | 小于 |
| <= | 小于等于 |
| = | 等于 |
| <> 或 != | 不等于 |
| between… and… | 在某个范围内(含最小、最大值) |
| in(…) | 在in之后的列表中的值,多选一 |
| like占位符 | 模糊匹配:_匹配单个字符,%匹配任意个字符 |
| is null | 是NULL |
| 逻辑运算符 | 功能 |
|---|---|
| and 或 && | 并且(多个条件同时成立) |
| or 或 || | 或者(多个条件任意一个成立) |
| not 或 ! | 非,不是 |
# 没有身份证
select * from employee where idcard is null ;
# 不等于
select * from employee where age != 30; #<> 30
# 年龄在20到30之间
select * from employee where age between 20 and 30;
# 下面语句不报错,但查不到任何信息
select * from employee where age between 30 and 20;
# 年龄等于25或30或35
select * from employee where age = 25 or age = 30 or age = 35;
select * from employee where age in (25, 30, 35);
# 姓名为两个字
select * from employee where name like '__';
# 身份证最后为X
select * from employee where idcard like '%X';
聚合函数
| 函数 | 功能 |
|---|---|
| count | 统计数量 |
| max | 最大值 |
| min | 最小值 |
| avg | 平均值 |
| sum | 求和 |
select 聚合函数(字段列表) from 表名;
select count(*) from emp where age = 88;
# NULL值不参与所有聚合函数运算 但select*还是会显示,只是单独的字段时
分组查询
select 字段列表 from 表名 [where 条件]
group by 分组字段名 [having 分组后的过滤条件];
where 和 having 的区别:
- 执行时机不同:where是分组之前进行过滤,不满足where条件不参与分组;having是分组后对结果进行过滤。
- 判断条件不同:where不能对聚合函数进行判断,而having可以。
-- 根据性别分组 , 统计男性员工 和 女性员工的数量
select gender, count(*) from emp group by gender;
-- 根据性别分组 , 统计男性员工 和 女性员工的平均年龄
select gender, avg(age) from emp group by gender;
-- 查询年龄小于45的员工 , 并根据工作地址分组 , 获取员工数量大于等于3的工作地址
select workaddress, count(*) as address from emp where age < 45 group by workaddress having address >= 3;
-- 执行顺序 where > 聚合函数 > having
-- 分组之后,select中查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义

排序查询
-- ASC 升序(默认)
-- DESC 降序 与前面查看表结构相同
-- 多字段排序,第一字段值相同时,才去根据第二字段规则排序
select 字段 from 表名 order by 字段1 排序方式1, 字段2 排序方式2;
分页查询
select 字段列表 from 表名 limit 起始索引, 查询记录数;
-- 起始索引从0开始,起始索引 = (查询页码 - 1) * 每页显示记录数
-- 分页查询是数据库的方言,不同数据库有不同实现,MySQL是LIMIT
-- 如果查询的是第一页数据,起始索引可以省略,直接简写 LIMIT 10
执行顺序
-- FROM -> WHERE -> GROUP BY -> SELECT -> ORDER BY -> LIMIT

DCL(数据控制语言)
管理用户
-
创建用户
create user '用户名'@'主机名' identified by '密码'; create user 'test1'@'localhost' ... # 当前主机访问 create user 'test2'@'%' ... # 任意主机访问 -
修改用户密码
alter user '用户名'@'主机名' identified with mysql_native_password by '新密码'; -
删除用户
drop user '用户名'@'主机名';
权限控制
| 权限 | 说明 |
|---|---|
| ALL, ALL PRIVILEGES | 所有权限 |
| SELECT | 查询数据 |
| INSERT | 插入数据 |
| UPDATE | 修改数据 |
| DELETE | 删除数据 |
| ALTER | 修改表 |
| DROP | 删除数据库/表/视图 |
| CREATE | 创建数据库/表 |
-
查询权限
show grants for '用户名'@'主机名'; -
授予权限
grant 权限列表 on 数据库名.表名 to '用户名'@'主机名'; -
撤销权限
revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
多个权限用逗号分隔
授权时,数据库名和表名可以用 * 进行通配,代表所有
函数
字符串函数
| 函数 | 功能 |
|---|---|
| concat(s1, s2, …, sn) | 字符串拼接,将s1, s2, …, sn拼接成一个字符串 |
| lower(str) | 将字符串全部转为小写 |
| upper(str) | 将字符串全部转为大写 |
| lpad(str, n, pad) | 左填充,用字符串pad对str的左边进行填充,达到n个字符串长度 |
| rpad(str, n, pad) | 右填充,用字符串pad对str的右边进行填充,达到n个字符串长度 |
| trim(str) | 去掉字符串头部和尾部的空格 |
| substring(str, start, len) | 返回从字符串str从start位置起的len个长度的字符串 |
| replace(column, source, replace) | 替换字符串 |
-- 拼接
select concat('Hello', 'World');
-- 小写
select lower('Hello');
-- 大写
select upper('Hello');
-- 左填充
select lpad('01', 5, '-');
-- 右填充
select rpad('01', 5, '-');
-- 去除空格
select trim(' Hello World ');
-- 切片(起始索引为1)
select substring('Hello World', 1, 5);
-- 将企业员工的工号统一为5位数,不足的前面补0
update emp set workno = lpad(wordno, 5, '0');
数值函数
| 函数 | 功能 |
|---|---|
| ceil(x) | 向上取整 |
| floor(x) | 向下取整 |
| mod(x, y) | 返回x/y的模 |
| rand() | 返回0~1内的随机数 |
| round(x, y) | 求参数x的四舍五入值,保留y位小数 |
-- 生成一个六位数的随机验证码
select round(rand()*1000000, 0);
# 但是这种也会生成五位数的
select ipad(round(rand()*1000000, 0), 6, '0');
日期函数
| 函数 | 功能 |
|---|---|
| curdate() | 返回当前日期 |
| curtime() | 返回当前时间 |
| now() | 返回当前日期和时间 |
| year(date) | 获取指定date的年份 |
| month(date) | 获取指定date的月份 |
| day(date) | 获取指定date的日期 |
| date_add(date, INTERVAL expr type) | 返回一个日期/时间值加上一个时间间隔expr后的时间值 |
| datediff(date1, date2) | 返回起始时间date1和结束时间date2之间的天数 |
select curdate(); # 当前日期
select now(); # 当前日期+时间
select month(now()); #
select date_add(now(), interval 70 day); # 当前时间间隔70天后
select datediff(now(), '2019-9-10'); # 求日期差值,可以是负数
-- 查询所有员工入职天数,并倒序排序
select name, datediff(curdate(), entrydate) as days
from emp
order by days desc;
流程函数
| 函数 | 功能 |
|---|---|
| if(value, t, f) | 如果value为true,则返回t,否则返回f |
| ifnull(value1, value2) | 如果value1不为空,返回value1,否则返回value2 |
| case when[ val1 ] THEN [ res1 ] … ELSE [ default ] end | 如果val1为true,返回res1,… 否则返回default默认值 |
| case[ expr ] WHEN [ val1 ] THEN [ res1 ] … ELSE [ default ] END | 如果expr的值等于val1,返回res1,… 否则返回default默认值 |
-- 查询员工姓名和工作地点,但北京和上海显示为一线城市,其余二线
select
name,
(case workaddress
when '北京市' then '一线城市'
when '上海市' then '一线城市'
else '二线城市' end) as '工作地址'
from employee;
-- 展示成绩等级
select
id,
name,
(case when math >= 80 then '优秀'
else '良好' end) as '数学',
(case when english >= 80 then '优秀'
else '良好' end) as '英语'
from emp;
约束
| 约束 | 描述 | 关键字 |
|---|---|---|
| 非空约束 | 限制该字段的数据不能为null | NOT NULL |
| 唯一约束 | 保证该字段的所有数据都是唯一、不重复的 | UNIQUE |
| 主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | PRIMARY KEY |
| 默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | DEFAULT |
| 检查约束(8.0.16版本后) | 保证字段值满足某一个条件 | CHECK |
| 外键约束 (少用) |
用来让两张图的数据之间建立连接,保证数据的一致性和完整性 | FOREIGN KEY |
约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束
| 约束条件 | 关键字 |
|---|---|
| 主键 | primary key |
| 自动增长 | auto_increment |
| 不为空 | not null |
| 唯一 | unique |
| 逻辑条件 | check |
| 默认值 | default |
create table user(
id int primary key auto_increment comment '主键',
name varchar(10) not null unique comment '姓名',
age int check(age > 0 and age < 120) comment '年龄',
status char(1) default '1',
gender char(1) comment '性别'
);
# 多个约束之间空格分隔
insert into user(name, age, status, gender) values();
# 主键自增时,插入数据可以不表明
# varchar时 ''并不是null
# unique是申请完空间后的唯一判断,所以即使重复也会占用一个自增的主键序号
# 但插入数据check()未通过时,查询优化器自动判定结果为空,不做任何IO操作,在unique判断之前
外键约束
外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性
-
添加外键
create table 表名( 字段名 字段类型, ... [constraint] [外键名称] foreign key(外键字段名) references 主表(主表列名) ); alter table 表名 add constraint 外键名称 foreign key (子表的外键字段) references 主表(主表列名); -- 例子 alter table emp add constraint fk_emp_dept_id foreign key(dept_id) references dept(id); -
删除外键
alter table 表名 drop foreign key 外键名字;
本文来自博客园,作者:小柴cyl,转载请注明原文链接:https://www.cnblogs.com/cyl018/p/17873924.html

浙公网安备 33010602011771号