[MySQL基础3] 数据控制语言DCL和MySQL中的常用函数

DCL,即Data Control Language,用来管理数据库的用户和其访问权限


1. 用户管理

  • 用户查询:

    用户都在MySQL自带的user数据库中

    mysql 复制代码
    mysql> use mysql;
    
    mysql> select User from user;
    +------------------+
    | User             |
    +------------------+
    | mysql.infoschema |
    | mysql.session    |
    | mysql.sys        |
    | root             |
    +------------------+
    4 rows in set (0.00 sec)
  • 创建用户:

    一个用户由用户名和主机名(localhost)定义

    mysql 复制代码
    create user 用户名@主机名 identified by 密码;
    mysql 复制代码
    mysql> create user jack@localhost identified by '123';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> select User from user;
    +------------------+
    | User             |
    +------------------+
    | jack             |
    | mysql.infoschema |
    | mysql.session    |
    | mysql.sys        |
    | root             |
    +------------------+
    5 rows in set (0.00 sec)
    
    mysql> -- 在任意主机访问数据库
    mysql> create user amy@'%' identified by '123';
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> select User from user;
    +------------------+
    | User             |
    +------------------+
    | amy              |
    | jack             |
    | mysql.infoschema |
    | mysql.session    |
    | mysql.sys        |
    | root             |
    +------------------+
    6 rows in set (0.00 sec)
  • 修改用户密码

    mysql 复制代码
    alter user 用户名@主机名 identified with mysql_native_password by 新密码

    其中mysql_native_password意为MySQL的本地密码

    mysql 复制代码
    mysql> alter user amy identified with mysql_native_password by 'abc';
    Query OK, 0 rows affected (0.01 sec)
  • 删除用户

    mysql 复制代码
    drop user 用户名@主机名
    mysql 复制代码
    mysql> drop user jack@localhost;
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> drop user amy@'%';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select User from user;
    +------------------+
    | User             |
    +------------------+
    | mysql.infoschema |
    | mysql.session    |
    | mysql.sys        |
    | root             |
    +------------------+
    4 rows in set (0.00 sec)

2. 权限控制

常用的权限有以下几种:

名称 说明
all, all privileges 所有权限
select 查询数据
insert 插入数据
update 修改数据
delete 删除数据
alter 修改表
drop 删除数据库/表/视图
create 创建数据库/表

基本的常用命令:

  • 查询权限:

    mysql 复制代码
    show grants for 用户名@主机名
  • 授予权限:

    mysql 复制代码
    grant 权限列表 on 数据库名.表名 to 用户名@主机名

    注意, 授予和撤销都是要指定哪个数据库的哪个表数据库名.表名

  • 撤销权限:

    mysql 复制代码
    revoke 权限列表 on 数据库名.表名 from 用户名@主机名

例子:

mysql 复制代码
mysql> show grants for jack@localhost;
+------------------------------------------+
| Grants for jack@localhost                |
+------------------------------------------+
| GRANT USAGE ON *.* TO `jack`@`localhost` |
+------------------------------------------+

-- 上面的意思是没有任何权限 仅能登录

-- 授予jack对info.user表格的所有权限
mysql> grant all on info.user to jack@localhost;
Query OK, 0 rows affected (0.01 sec)

-- 查看权限
mysql> show grants for jack@localhost;
+-------------------------------------------------------------+
| Grants for jack@localhost                                   |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO `jack`@`localhost`                    |
| GRANT ALL PRIVILEGES ON `info`.`user` TO `jack`@`localhost` |
+-------------------------------------------------------------+

-- 登录jack用户后 可以查看到info数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| info               |
| information_schema |
| performance_schema |
+--------------------+

-- 撤销jack用户权限(在root下)
mysql> revoke all on info.user from jack@localhost;
Query OK, 0 rows affected (0.01 sec)

-- 这时jack能看到的数据库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)

-- 授予jack特定的权限
mysql> grant select, insert, update on info.user to jack@localhost;
Query OK, 0 rows affected (0.01 sec)

-- 从jack登录,可以插入,查询,更改表的数据
mysql> use info;
Database changed

mysql> insert into user values (1, 'aaa', 'F'), (2, 'bbb', 'M');
Query OK, 2 rows affected (0.01 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from user where gender='F';
+------+------+--------+
| id   | name | gender |
+------+------+--------+
|    1 | aaa  | F      |
+------+------+--------+

mysql> update user set name='qwe' where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from user;
+------+------+--------+
| id   | name | gender |
+------+------+--------+
|    1 | qwe  | F      |
|    2 | bbb  | M      |
+------+------+--------+
2 rows in set (0.00 sec)

-- 但是没有删除表的权限
mysql> drop table user;
ERROR 1142 (42000): DROP command denied to user 'jack'@'localhost' for table 'user'

介绍一下MySQL中的函数,主要分为四大类:字符串函数、数值函数、日期函数和流程函数


1. 字符串函数

MySQL中常用的内置字符串函数如下:

函数 功能
concat(str1, ..., strn) 拼接字符串, 相当于Java StringBuilder的append()
lower(str) 转换为小写, 相当于python的lower()
upper(str) 转换为大写, 相当于python的upper()
lpad(str, n, pad) 用pad左填充至长度n, 相当于格式化字符串'%{pad}{n}s'.format(str)
rpad(str, n, pad) 用pad右填充至长度n
trim(str) 去掉字符串头尾空格, 相当于python的strip()
substring(str, st, len) 去从下标st开始长度为len的子串, 相当于C++的substr(). 注意索引从1开始!

例子:

mysql 复制代码
-- 用select做到打印内容
mysql> select concat('ab', 'cd');
+--------------------+
| concat('ab', 'cd') |
+--------------------+
| abcd               |
+--------------------+

mysql> select lower('asda'), upper('fdf');
+---------------+--------------+
| lower('asda') | upper('fdf') |
+---------------+--------------+
| asda          | FDF          |
+---------------+--------------+

mysql> select lpad('123', 10, '-'), rpad('123', 10, '*');
+----------------------+----------------------+
| lpad('123', 10, '-') | rpad('123', 10, '*') |
+----------------------+----------------------+
| -------123           | 123*******           |
+----------------------+----------------------+

mysql> select trim('  asdsd3  ');
+--------------------+
| trim('  asdsd3  ') |
+--------------------+
| asdsd3             |
+--------------------+

mysql> select substring('qwerty', 2, 3);
+---------------------------+
| substring('qwerty', 2, 3) |
+---------------------------+
| wer                       |
+---------------------------+

一个小案例:将user表中name的前面补0,至10位数。

mysql 复制代码
mysql> select * from user;
+------+------+--------+
| id   | name | gender |
+------+------+--------+
|    1 | qwe  | F      |
|    2 | bbb  | M      |
+------+------+--------+


mysql> update user set name=lpad(name, 5, '0');
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from user;
+------+-------+--------+
| id   | name  | gender |
+------+-------+--------+
|    1 | 00qwe | F      |
|    2 | 00bbb | M      |
+------+-------+--------+

2. 数值函数

MySQL中常用的内置数值函数如下,跟绝大多数语言的用法都是一样的:

函数 功能
ceil(x) 向上取整,Java: Math.ceil(), Python: math.ceil()
floor(str) 向下取整,Java: Math.floor(), Python: math.floor(),
mod(x, y) 计算x % y
rand() 0~1内随机数
round(x, y) 四舍五入x, 保留y位小数
mysql 复制代码
mysql> select ceil(1.3), floor(3.3), round(1/3, 3);
+-----------+------------+---------------+
| ceil(1.3) | floor(3.3) | round(1/3, 3) |
+-----------+------------+---------------+
|         2 |          3 |         0.333 |
+-----------+------------+---------------+
1 row in set (0.01 sec)

mysql> select mod(5, 2), rand();
+-----------+--------------------+
| mod(5, 2) | rand()             |
+-----------+--------------------+
|         1 | 0.5711282347991394 |
+-----------+--------------------+
1 row in set (0.01 sec)

3. 日期函数

MySQL中常用的日期函数如下:

函数 功能
curdate() 当前日期
curtime() 当前时间
now() 当前日期和时间
year(date), month(date), day(date) 获取指定date的年份,月份,日
date_add(date, interval expr type) 返回一个日期/时间值加上一个时间间隔expr后的时间值
datediff(date1, date2) 返回date1和date2之间的天数
mysql 复制代码
mysql> select curdate(), curtime(), now();
+------------+-----------+---------------------+
| curdate()  | curtime() | now()               |
+------------+-----------+---------------------+
| 2025-07-19 | 15:31:28  | 2025-07-19 15:31:28 |
+------------+-----------+---------------------+

mysql> select year('2024-3-3'), month('2025-04-21'), day(now());
+------------------+---------------------+------------+
| year('2024-3-3') | month('2025-04-21') | day(now()) |
+------------------+---------------------+------------+
|             2024 |                   4 |         19 |
+------------------+---------------------+------------+

mysql> select date_add(now(), interval 2 day), date_add(curdate(), interval 3 month), date_add(now(), interval 1 year);
+---------------------------------+---------------------------------------+----------------------------------+
| date_add(now(), interval 2 day) | date_add(curdate(), interval 3 month) | date_add(now(), interval 1 year) |
+---------------------------------+---------------------------------------+----------------------------------+
| 2025-07-21 15:34:59             | 2025-10-19                            | 2026-07-19 15:34:59              |
+---------------------------------+---------------------------------------+----------------------------------+

mysql> select date_add(now(), interval 2 second);
+------------------------------------+
| date_add(now(), interval 2 second) |
+------------------------------------+
| 2025-07-19 15:39:36                |
+------------------------------------+
1 row in set (0.00 sec)

mysql> select date_add(now(), interval 2 week);
+----------------------------------+
| date_add(now(), interval 2 week) |
+----------------------------------+
| 2025-08-02 15:39:37              |
+----------------------------------+
1 row in set (0.00 sec)

mysql> select datediff('2025-3-2 13:32:19', now());
+--------------------------------------+
| datediff('2025-3-2 13:32:19', now()) |
+--------------------------------------+
|                                 -139 |
+--------------------------------------+

案例:为user表格中增加日期列,并按照日期从早到晚排序查询

mysql 复制代码
mysql> alter table user add column entrydate date;
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0

-- 设定数据的时间,并且再增加一列
mysql> update user set entrydate='2025-01-01' where id=1;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> update user set entrydate=curdate() where id=2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> insert into user values (3, 'asdasd', 'F', '2020-4-2');
Query OK, 1 row affected (0.01 sec)

-- 查看一下
mysql> select * from user;
+------+--------+--------+------------+
| id   | name   | gender | entrydate  |
+------+--------+--------+------------+
|    1 | qwe    | F      | 2025-01-01 |
|    2 | bbb    | M      | 2025-07-19 |
|    3 | asdasd | F      | 2020-04-02 |
+------+--------+--------+------------+
3 rows in set (0.00 sec)

-- 排序查询 日期从早到晚也就是距离今天从大到小
mysql> select name, datediff(curdate(), entrydate) as d from user order by d desc;
+--------+------+
| name   | d    |
+--------+------+
| asdasd | 1934 |
| qwe    |  199 |
| bbb    |    0 |
+--------+------+
3 rows in set (0.00 sec)

4. 流程控制函数

MySQL中常用的流程控制函数如下:

函数 功能
if(value, t, f) 如果value是true,返回t,否则f,相当于Java/C++三元运算符value ? t : f;
ifnull(v1, v2) 如果v1不是null返回v1,否则返回v2,相当于Java/C++v1 == null ? v2 : v1;
case when [val1] then [ret1]...else [defalut] end 如果val1为true则返回ret1,以此类推,最终返回default
case [expr] when [val1] then [ret1]...else [defalut] end 如果expr的值为val1则返回ret1,以此类推,最终返回default. 相当于Java/C++的switch...case...default
mysql 复制代码
mysql> select if(datediff(now(), '2024-3-4') > 0, 'yes', 'no');
+--------------------------------------------------+
| if(datediff(now(), '2024-3-4') > 0, 'yes', 'no') |
+--------------------------------------------------+
| yes                                              |
+--------------------------------------------------+

mysql> select ifnull(null, '123');
+---------------------+
| ifnull(null, '123') |
+---------------------+
| 123                 |
+---------------------+

-- 实现需求:查询表user,如果性别是F,就显示'女',性别是M,就显示'男'
mysql> select name,
    -> (case gender when 'F' then '女' when 'M' then '男' else '不男不女' end) as gen
    -> from user;
+--------+-----+
| name   | gen |
+--------+-----+
| qwe    | 女  |
| bbb    | 男  |
| asdasd | 女  |
+--------+-----+
3 rows in set (0.01 sec)
相关推荐
zl0_00_03 分钟前
pctf wp
学习
苏三说技术4 分钟前
xxl-job 和 elastic-job,哪个更好?
后端
Hello_Embed10 分钟前
libmodbus STM32 主机实验(USB 串口版)
笔记·stm32·学习·嵌入式·freertos·modbus
hlABgYML10 分钟前
基于NGSIM数据的Wiedemann99跟驰模型标定
mysql
学编程的闹钟11 分钟前
98【html的php化】
学习
三小河13 分钟前
Agent Skill与Rules的区别——以Cursor为例
前端·javascript·后端
risc12345625 分钟前
思维脚手架
笔记
三小河26 分钟前
前端视角详解 Agent Skill
前端·javascript·后端
数据知道28 分钟前
PostgreSQL 性能优化:分区表实战
数据库·postgresql·性能优化
林开落L30 分钟前
从零开始学习Protobuf(C++实战版)
开发语言·c++·学习·protobuffer·结构化数据序列化机制