欢迎光临
我们一直在努力

MySql基础夯实:从配置到掌握(看这一篇就够了!)

一、了解MySQL

1.简介

MySQL 是目前全球最主流的 开源 关系型 数据库管理系统(RDBMS),也是 Java 后端开发的标配组件

通俗理解:它就是一个专门用来「永久存数据、高效管数据」的专业软件。你可以把它想象成一个超级加强版的 Excel 表格仓库:

  • 数据按「表格」组织,每张表有固定的列(字段,比如姓名、手机号),每一行是一条完整数据
  • 支持用标准化的 SQL 语言,对数据进行增、删、改、查
  • 能承载百万、千万级数据,支持成百上千人同时操作,还能保证数据安全、不丢失

其中SQL(Structure Quer Language)是一种操控关系型数据库的语言,几乎所有关系型数据库都支持SQL

所以如果想用好并理解MySQL,最好//还是先学习SQL基础语言(下面是我的SQL笔记)

SQL语言基础:关系型数据库的通用语言(超详细版,看这一篇就够了!)-CSDN博客

(当然,由于Navicat等可视化工具的出现,其实不了解原始代码也可以操作数据库,不过在Java中更改数据库还是需要用到SQL语言哦)

2.能解决什么问题?

它最核心的价值是数据持久化。 你写的 Java 程序运行时,所有数据都暂存在内存里,程序一关闭、电脑一重启,数据就会全部消失。 而 MySQL 会把数据写入硬盘永久保存,程序下次启动还能读取到历史数据。

除此之外它还承担这些核心能力:

  • 高效查询:哪怕表里有上百万条数据,也能在毫秒级精准查到你要的内容
  • 并发控制:多人同时修改同一条数据时,保证不会出现数据错乱
  • 事务保障:保证一组操作要么全部成功、要么全部失败
  • 权限与安全:可以设置不同账号的读写权限,支持数据备份、误删恢复
  • 数据统计:可以快速做汇总、排序、分组统计,生成业务报表
  • 3.为什么选择MySQL?

    几乎所有需要持久化存储数据的软件系统,都可以用 MySQL:

    • 网站、小程序、APP 的后端数据存储(电商、外卖、校园系统、社交平台)
    • 企业内部管理系统(OA 办公、CRM 客户管理、ERP 进销存)
    • 博客、论坛、内容管理系统
    • 数据后台、报表统计、数据分析系统

    因为它开源免费、生态成熟、Java 支持度极高,所以是中小项目和互联网公司的首选数据库。

    4.用户权限说明

    MySQL 权限按作用范围从大到小分为 4 个层级:全局层级 > 数据库层级 > 表层级 > 列层级,高层级权限会自动覆盖低层级范围。以下是开发与运维中最常用的权限分类明细:

    (1)数据操作类权限(业务开发核心权限)

    这类权限用于控制数据的增删改查,是普通业务用户最常用的权限。

    表格

    权限名称功能说明支持层级
    SELECT 查询数据,读取表中字段内容 全局、库、表、列
    INSERT 向表中插入新增数据行 全局、库、表、列
    UPDATE 修改表中已有的数据内容 全局、库、表、列
    DELETE 删除表中的数据行 全局、库、表

    (2)结构操作类权限(DDL 权限)

    这类权限用于控制数据库、表、索引等结构的创建与修改,一般仅授予开发或运维账号,业务读写账号不建议开放。

    表格

    权限名称功能说明支持层级
    CREATE 创建新的数据库、数据表 全局、库、表
    DROP 删除数据库、数据表、视图 全局、库、表
    ALTER 修改表结构(增减字段、调整字段类型等) 全局、库、表
    INDEX 创建、删除、修改表索引 全局、库、表
    CREATE VIEW 创建视图 全局、库、表
    SHOW VIEW 查看视图的定义语句 全局、库、表
    CREATE ROUTINE 创建存储过程、函数 全局、库
    ALTER ROUTINE 修改、删除存储过程、函数 全局、库
    EXECUTE 执行存储过程、函数 全局、库、表

    (3)管理类权限(仅管理员账号使用)

    这类权限涉及数据库服务的全局管理,生产环境严禁授予普通业务用户。

    表格

    权限名称功能说明支持层级
    ALL PRIVILEGES 授予除 GRANT OPTION 外的所有常规权限,可简写为 ALL 全部层级
    GRANT OPTION 允许将自身拥有的权限授予其他用户,或回收其他用户的权限 全部层级
    CREATE USER 创建、删除、重命名用户账号 全局
    SHOW DATABASES 查看服务器上所有数据库的列表 全局
    PROCESS 查看所有用户的数据库连接进程,可终止会话 全局
    SUPER 超级管理权限,可修改全局参数、终止任意进程等 全局
    FILE 读写数据库服务器本地的文件(用于数据导入导出) 全局
    RELOAD 执行 FLUSH 类命令,刷新权限、日志、缓存等 全局
    SHUTDOWN 关闭数据库服务 全局
    REPLICATION SLAVE 从库复制账号专用权限,用于主从数据同步 全局

    (4)基础与特殊权限

    表格

    权限名称功能说明支持层级
    USAGE 无任何业务权限,仅允许登录数据库。新建用户默认只有此权限 全局
    REFERENCES 创建外键约束的权限 全局、库、表、列

    补充说明

  • 权限生效范围示例

    • *.* 代表全局层级:所有数据库的所有表
    • test_db.* 代表库层级:test_db 库下的所有表
    • test_db.emp 代表表层级:test_db 库下的 emp 表
    • 列层级写法示例:GRANT SELECT(emp_id, emp_name) ON test_db.emp TO …,仅允许查看指定列
  • ALL PRIVILEGES 注意点 它不等于 root 账号的全部权限,仅包含常规的读写、结构操作权限,不包含 GRANT OPTION、SUPER 等超级管理权限。

  • 最小权限原则 业务账号只授予必需的 SELECT、INSERT、UPDATE、DELETE 即可,严禁随意开放 ALL PRIVILEGES 或全局权限。

  • 二、实践

    1.安装配置

    (1)下载数据库

    首先到官网(MySQL)下载数据库

    如果下载的是压缩包免安装版本,需要进行解压操作:

    首先将压缩包解压到纯英文、无空格、无特殊字符的路径下,例如:

    D:\\mysql-8.0.39-winx64

    ❌ 错误路径示例:C:\\Program Files\\mysql(有空格)、D:\\软件\\mysql(有中文)

    解压完成后,根目录下会有 bin、docs、include 等文件夹,没有 data 文件夹(后面初始化会自动生成)

    (2)编写配置文件

    接着手动编写配置文件my.ini (MySQL 启动时会读取这个配置文件,用来指定 安装路径、数据存储路径、端口、字符集 等核心参数)

    • 在 MySQL 解压的根目录(和 bin 文件夹同级),新建一个文本文档,重命名为 my.ini(注意后缀名从 .txt 改成 .ini)
    • 用记事本打开,粘贴以下基础配置,必须把路径改成你自己的解压路径:

    [mysqld]
    # MySQL 解压根目录,路径用双反斜杠 \\\\ 或正斜杠 / 都可以
    basedir=D:\\\\mysql-8.0.39-winx64
    # 数据库数据存放目录,会自动生成,不要手动新建
    datadir=D:\\\\mysql-8.0.39-winx64\\\\data
    # 服务监听端口,默认3306
    port=3306
    # 允许的最大连接数
    max_connections=200
    # 服务端默认字符集,推荐utf8mb4(支持完整emoji)
    character-set-server=utf8mb4
    # 默认存储引擎
    default-storage-engine=INNODB

    [mysql]
    # 客户端默认字符集
    default-character-set=utf8mb4

    • 保存文件,编码保持默认 ANSI 即可,不要存成带 BOM 的 UTF-8,否则会识别失败。

    (3)配置环境变量(可选)

    配置完以后可以选择配置系统环境变量,配置后可以在任意位置打开 CMD 执行 mysql 命令,不用每次都进入 bin 目录(也可以选择跳过这步)

    操作步骤:

    • 右键「此电脑」→「属性」→「高级系统设置」→「环境变量」
    • 在下方「系统变量」里找到 Path,双击编辑
    • 点击「新建」,填入你的 MySQL 的 bin 目录路径

    (4)初始化数据库

    然后就可以初始化数据库了(这一步是 ZIP 版独有的,用来生成数据目录和 root 账号的初始密码,全程必须用管理员身份执行)

    • 按下 Win 键,搜索 cmd,右键「命令提示符」→以管理员身份运行

    • 如果你配置了环境变量,直接执行命令;没配置的话,先 cd /d D:\\mysql-8.0.39-winx64\\bin 进入 bin 目录

    • 执行初始化命令:

    mysqld –initialize –console

    • –initialize:执行初始化,自动创建 data 目录、系统表、root 账号
    • –console:把初始化日志打印在控制台,初始密码会显示在这里,一定要记下来
    • 执行完成后,在控制台最后几行找到类似下面的内容,冒号后面的就是 root 用户的临时初始密码,复制保存好:

    A temporary password is generated for root@localhost: xxxxxxxx

    (注意:如果初始化报错,先把自动生成的 data 文件夹整个删掉,检查 my.ini 里的路径是否正确、路径有没有中文空格,修正后重新执行初始化命令)

    (5)注册(卸载)系统服务

    接下来注册为Windows系统服务,

    注册后就可以像安装版一样,通过服务面板或命令一键启停,还能设置开机自启。

    保持管理员 CMD 窗口,执行命令:

    mysqld –install MySQL80

    • MySQL80 是自定义的服务名,可以自己改,后面启停都用这个名字
    • 执行成功会提示 Service successfully installed.

    如果以后想卸载服务,执行:

    mysqld –remove MySQL80

    (6)启动服务并修改密码

    1)启动MySQL服务

    net start MySQL80

    执行成功会提示「MySQL80 服务已经启动成功」,此时数据库就已经在后台运行了

    2)登陆并修改初始密码

    初始随机密码只能用来第一次登录,必须修改成自己的密码才能正常使用。

    • 执行登录命令,回车后输入刚才保存的临时密码:

    mysql -u root -p

    • 成功进入 MySQL 命令行后,执行修改密码命令(把 你的新密码 换成你自己的密码):

    ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';

    • 执行完成后,输入 quit 退出,用新密码重新登录一次,验证修改成功。

    (7)日常使用

    配置完成后,就不用再做初始化、注册服务这些操作了,日常启停和安装版完全一致(二选一):

    • 图形化:Win+R 输入 services.msc,找到 MySQL80 服务右键启停
    • 命令行(管理员 CMD):

    net start MySQL80 # 启动
    net stop MySQL80 # 停止

    配置完成后,项目就可以通过 localhost:3306,用 root 账号和设置的密码连接本地数据库了

    2.连接MySQL

    1)使用MySQL自带的客户端连接

    在命令提示符中执行上面的登录命令后输入密码即可,show databases; 可以查看数据库

    这种方式不怎么方便

    2)使用Navicat工具连接MySQL

    首先先去官网下载 Navicat | 免费下载 Navicat Premium Lite (这是一个轻量免费版)

    然后点击新建连接,自定义名字后输入密码,点击连接测试,如果显示成功,点击确定即可创建

    双击左侧列表连接名会自动激活链接(展开列表是库)

    (这里主要进行基础语句讲解,可视化软件用法后面可能会单开一章讲解,其实也很简单没啥可讲的,毕竟都可视化了)

    3.函数

    tips.MySQL再进行字符串查询工作时会自动忽略字符的大小写区别(默认状态下,除非在创建表时加入了binary关键字)

    (1)单行函数

    1)字符函数

    示例基于 utf8mb4 字符集,select语句使用

    分类函数名称语法格式功能说明示例与返回结果
    拼接与长度 CONCAT() CONCAT(str1, str2, …) 拼接多个字符串为一个字符串;任意一个参数为 NULL,返回结果就是 NULL CONCAT('姓名:', '张三') → 姓名:张三
    CONCAT_WS() CONCAT_WS(分隔符, str1, str2, …) 带分隔符拼接字符串;分隔符不能为 NULL,值为 NULL 的参数会被自动忽略 CONCAT_WS('-', '2025', '08', '10') → 2025-08-10
    CHAR_LENGTH() CHAR_LENGTH(str) 返回字符串的字符个数,中文、英文、数字均算 1 个字符 CHAR_LENGTH('你好abc') → 5
    LENGTH() LENGTH(str) 返回字符串的字节长度;utf8mb4 下常用汉字占 3 字节、英文 / 数字占 1 字节 LENGTH('你好abc') → 9
    字符串截取 SUBSTRING() / SUBSTR() SUBSTRING(str, 起始位置)SUBSTRING(str, 起始位置, 长度) 截取字符串子串;位置从 1 开始计数;不写长度则截取到末尾 SUBSTRING('abcdef', 2, 3) → bcd
    LEFT() LEFT(str, n) 从字符串左侧截取 n 个字符 LEFT('hello', 3) → hel
    RIGHT() RIGHT(str, n) 从字符串右侧截取 n 个字符 RIGHT('hello', 2) → lo
    大小写转换 UPPER() / UCASE() UPPER(str) 将字符串全部转为大写 UPPER('hello') → HELLO
    LOWER() / LCASE() LOWER(str) 将字符串全部转为小写 LOWER('HELLO') → hello
    空格与填充 TRIM() TRIM(str)TRIM(要移除的字符 FROM str) 去除字符串首尾空格;也可指定去除首尾的特定字符 TRIM(' abc ') → abc
    LTRIM() LTRIM(str) 仅去除字符串左侧空格 LTRIM(' abc') → abc
    RTRIM() RTRIM(str) 仅去除字符串右侧空格 RTRIM('abc ') → abc
    LPAD() LPAD(str, 总长度, 填充字符) 左侧填充字符,使字符串达到指定总长度,常用于补零对齐 LPAD('123', 5, '0') → 00123
    RPAD() RPAD(str, 总长度, 填充字符) 右侧填充字符,使字符串达到指定总长度 RPAD('123', 5, '*') → 123**
    替换与查找 REPLACE() REPLACE(str, 旧子串, 新子串) 将字符串中所有的旧子串替换为新子串 REPLACE('hello world', 'world', 'MySQL') → hello MySQL
    INSTR() INSTR(str, 子串) 返回子串第一次出现的位置,找不到返回 0;位置从 1 开始 INSTR('abcdef', 'cd') → 3
    LOCATE() LOCATE(子串, str)LOCATE(子串, str, 起始位置) 查找子串位置,可指定从第几个字符开始查找 LOCATE('a', 'banana', 2) → 3
    其他常用 REVERSE() REVERSE(str) 反转字符串顺序 REVERSE('abc') → cba
    ELT() ELT(n, str1, str2, str3…) 按索引 n 返回对应字符串;n=1 返回 str1,超出范围返回 NULL ELT(2, '男', '女', '未知') → 女
    FIELD() FIELD(str, str1, str2, str3…) 返回字符串在列表中的索引位置;找不到返回 0,与 ELT 功能相反 FIELD('女', '男', '女', '未知') → 2
    注意事项
  • 位置索引从 1 开始:所有涉及字符串位置的函数(SUBSTRING、INSTR 等),第一个字符的位置都是 1,不是 0。
  • NULL 值陷阱:CONCAT() 只要有一个参数是 NULL,整体结果就为 NULL;不确定字段是否为空时,建议先用 IFNULL() 做兜底处理。
  • 字符数 vs 字节数:CHAR_LENGTH() 统计字符个数,LENGTH() 统计字节长度,中文场景下两者差异极大,不要混用。
  • 索引失效风险:不要在 WHERE 条件中对索引字段使用字符函数,会导致索引失效,大幅降低查询性能。
  • 2)数字函数

    数值函数用于对数字类型数据执行数学计算、取整、格式化等操作,属于典型的单行函数:逐行运算,每行返回一个计算结果

    分类函数名称语法格式功能说明示例与返回结果
    取整与截断 ROUND() ROUND(x, 小数位数) 对数值进行四舍五入;小数位数可省略,默认保留 0 位 ROUND(3.1415, 2) → 3.14ROUND(3.6) → 4
    CEIL() / CEILING() CEIL(x) 向上取整,返回大于等于参数的最小整数 CEIL(3.1) → 4CEIL(-3.1) → -3
    FLOOR() FLOOR(x) 向下取整,返回小于等于参数的最大整数 FLOOR(3.9) → 3FLOOR(-3.1) → -4
    TRUNCATE() TRUNCATE(x, 小数位数) 直接截断小数位,不做四舍五入 TRUNCATE(3.999, 2) → 3.99
    基础数学运算 ABS() ABS(x) 返回数值的绝对值 ABS(-10) → 10
    MOD() MOD(x, y) 取余运算,返回 x 除以 y 的余数,等价于运算符 % MOD(10, 3) → 1
    POW() / POWER() POW(x, y) 幂运算,返回 x 的 y 次方 POW(2, 3) → 8
    SQRT() SQRT(x) 返回非负数的平方根 SQRT(9) → 3
    符号与随机数 SIGN() SIGN(x) 返回数值的符号:正数返回 1,负数返回 -1,0 返回 0 SIGN(-5) → -1
    RAND() RAND()RAND(种子值) 生成 0~1 之间的随机浮点数;带固定种子时生成可重复的随机序列 RAND() → 0.628…(随机值)FLOOR(RAND() * 100) → 生成 0~99 的随机整数
    极值与格式化 GREATEST() GREATEST(v1, v2, v3…) 返回多个参数中的最大值 GREATEST(5, 12, 8) → 12
    LEAST() LEAST(v1, v2, v3…) 返回多个参数中的最小值 LEAST(5, 12, 8) → 5
    FORMAT() FORMAT(x, 小数位数) 将数字格式化为千分位格式,返回字符串类型,仅用于展示 FORMAT(12345.6789, 2) → 12,345.68
    注意事项
  • 负数取整方向易混淆 CEIL 是往数轴正方向取整,FLOOR 往负方向取整。例如 CEIL(-3.1) = -3,FLOOR(-3.1) = -4,不要凭直觉按 “数字变大变小” 判断。

  • ROUND 与 TRUNCATE 的本质区别

    • ROUND 按四舍五入规则保留小数
    • TRUNCATE 是直接砍掉多余小数位,不做进位 例如 ROUND(3.59, 1) = 3.6,而 TRUNCATE(3.59, 1) = 3.5。
  • 随机数通用公式 生成 [min, max] 区间随机整数的通用写法:

    FLOOR(最小值 + RAND() * (最大值 – 最小值 + 1))

    例:生成 1~100 的随机整数 → FLOOR(1 + RAND() * 100)。

  • NULL 值陷阱 所有数值函数输入参数为 NULL 时,返回结果也为 NULL,例如 ABS(NULL) 返回 NULL。

  • FORMAT 返回值是字符串 格式化后的结果带千分位逗号,属于字符串类型,不能直接继续做数学运算,仅用于最终结果展示

  • 3)日期函数

    日期函数属于单行函数,逐行对日期 / 时间类型数据执行计算,支持时间获取、分量提取、日期运算、格式转换等操作,是业务开发中的高频函数

    年月日用“-”或者“/”分隔

    分类函数名称语法格式功能说明示例与返回结果
    当前时间获取 NOW() / CURRENT_TIMESTAMP() NOW() 返回当前系统的日期 + 时间;取语句执行开始时的时间,同一条 SQL 中多次调用值不变 NOW() → 2026-08-10 15:42:30
    SYSDATE() SYSDATE() 返回函数执行瞬间的实时时间;同一条 SQL 中多次调用值可能不同 SYSDATE() → 2026-08-10 15:42:30
    CURDATE() / CURRENT_DATE() CURDATE() 仅返回当前日期,不包含时间 CURDATE() → 2026-08-10
    CURTIME() / CURRENT_TIME() CURTIME() 仅返回当前时间,不包含日期 CURTIME() → 15:42:30
    日期分量提取 YEAR() / MONTH() / DAY() YEAR(date) 分别提取日期中的年、月、日数值 YEAR('2026-08-10') → 2026MONTH('2026-08-10') → 8
    HOUR() / MINUTE() / SECOND() HOUR(time) 分别提取时间中的时、分、秒数值 HOUR('15:42:30') → 15
    DAYOFYEAR() DAYOFYEAR(date) 返回日期是当年的第几天(1~366) DAYOFYEAR('2026-02-01') → 32
    DAYOFWEEK() DAYOFWEEK(date) 返回日期是当周的第几天(周日 = 1,周六 = 7) DAYOFWEEK('2026-08-10') → 2(周一)
    DATE() / TIME() DATE(datetime) 从 datetime 类型中单独提取日期 / 时间部分 DATE(NOW()) → 2026-08-10
    日期加减运算 DATE_ADD() / ADDDATE() DATE_ADD(date, INTERVAL 数值 单位) 对日期执行加法运算,支持年 / 月 / 日 / 时 / 分 / 秒等单位 DATE_ADD('2026-08-10', INTERVAL 3 DAY) → 2026-08-13DATE_ADD(NOW(), INTERVAL 1 MONTH) → 一个月后
    DATE_SUB() / SUBDATE() DATE_SUB(date, INTERVAL 数值 单位) 对日期执行减法运算,单位与 DATE_ADD 一致 DATE_SUB('2026-08-10', INTERVAL 2 YEAR) → 2024-08-10
    LAST_DAY() LAST_DAY(date) 返回日期所在月份的最后一天 LAST_DAY('2026-02-01') → 2026-02-28
    日期差值计算 DATEDIFF() DATEDIFF(date1, date2) 计算两个日期相差的天数,规则:date1 – date2,结果可正可负 DATEDIFF('2026-08-10', '2026-08-01') → 9
    TIMEDIFF() TIMEDIFF(time1, time2) 计算两个时间的差值,返回 time 类型 TIMEDIFF('18:00:00', '09:00:00') → 09:00:00
    TIMESTAMPDIFF() TIMESTAMPDIFF(单位, date1, date2) 按指定单位计算时间差,规则:date2 – date1;常用单位:YEAR/MONTH/DAY/HOUR/MINUTE TIMESTAMPDIFF(YEAR, '2000-01-01', '2026-08-10') → 26
    格式化与转换 DATE_FORMAT() DATE_FORMAT(date, 格式串) 将日期 / 时间转为指定格式的字符串,最常用格式:%Y-%m-%d %H:%i:%s DATE_FORMAT(NOW(), '%Y年%m月%d日') → 2026年08月10日
    STR_TO_DATE() STR_TO_DATE(字符串, 格式串) 将符合格式的字符串转换为日期类型,是 DATE_FORMAT 的反向操作 STR_TO_DATE('08-10-2026', '%m-%d-%Y') → 2026-08-10
    其他常用 WEEK() / YEARWEEK() WEEK(date) 返回日期是当年的第几周;YEARWEEK 返回 年 + 周 组合值 WEEK('2026-01-05') → 1
    MONTHNAME() / DAYNAME() MONTHNAME(date) 返回月份 / 星期的英文名称 MONTHNAME('2026-08-10') → August
    注意事项
  • 格式符大小写敏感 DATE_FORMAT 的格式符区分大小写,最容易写错的几个:

    • %Y = 4 位年份(2026),%y = 2 位年份(26)
    • %H = 24 小时制,%h = 12 小时制
    • %i = 分钟,%s = 秒;分钟不是 %m(%m 是月份)
  • 差值函数参数顺序相反

    • DATEDIFF(date1, date2):前减后(date1 – date2)
    • TIMESTAMPDIFF(单位, date1, date2):后减前(date2 – date1) 两者顺序相反,是新手最容易写反、导致结果正负错误的点。
  • NOW() 与 SYSDATE() 的区别 NOW() 取 SQL 语句开始执行的时间,同一条 SQL 里多次调用值完全一致;SYSDATE() 取函数执行瞬间的实时时间,长 SQL 中多次调用会有差异。绝大多数业务场景使用 NOW() 即可。

  • 索引失效风险 不要在 WHERE 子句中对日期索引字段使用函数,例如 WHERE YEAR(create_time) = 2026 会导致索引失效。推荐改写为范围查询:

    WHERE create_time >= '2026-01-01' AND create_time < '2027-01-01'

  • NULL 值陷阱 所有日期函数的输入参数为 NULL 时,返回结果也为 NULL

  • 4)转换函数(显式)

    转换函数用于显式转换数据的类型、字符集或格式,属于单行函数。核心作用是规避隐式转换带来的逻辑异常、索引失效等问题,统一数据类型后再进行运算、比较或关联

    分类函数名称语法格式功能说明示例与返回结果
    核心类型转换 CAST() CAST(表达式 AS 目标类型) 标准 SQL 语法的类型转换函数,兼容性最强,将表达式的值转换为指定数据类型 CAST('123' AS SIGNED) → 123CAST(3.14 AS DECIMAL(3,1)) → 3.1CAST('2026-08-10' AS DATE) → 2026-08-10
    CONVERT()(类型转换) CONVERT(表达式, 目标类型) MySQL 专属类型转换,功能与 CAST 完全一致,仅语法格式不同(用逗号分隔) CONVERT('456abc', UNSIGNED) → 456
    字符集与校对转换 CONVERT()(字符集转换) CONVERT(表达式 USING 目标字符集) 将字符串转换为指定字符集,解决跨字符集乱码、关联比对异常问题 CONVERT('测试' USING gbk) → gbk 编码的字符串
    BINARY BINARY 表达式 强制将字符串转为二进制字符串,按字节逐位比对,天然大小写敏感 BINARY 'Admin' = 'admin' → 0(不相等)
    CHARSET() CHARSET(字符串) 返回当前字符串所属的字符集 CHARSET('你好') → utf8mb4
    COLLATION() COLLATION(字符串) 返回当前字符串的校对规则 COLLATION('abc') → utf8mb4_0900_ai_ci
    常用补充转换 STR_TO_DATE() STR_TO_DATE(字符串, 格式串) 将格式化字符串转换为 DATE/DATETIME 类型(日期类核心转换函数) STR_TO_DATE('2026-08-10', '%Y-%m-%d') → 2026-08-10
    DATE_FORMAT() DATE_FORMAT(日期, 格式串) 将日期类型转换为指定格式的字符串(日期类核心转换函数) DATE_FORMAT(NOW(), '%Y%m%d') → 20260810
    注意事项
  • 常用目标类型清单 CAST / CONVERT 支持的常用转换目标类型:

    • 字符串:CHAR(n)
    • 整数:SIGNED(有符号)、UNSIGNED(无符号)
    • 小数:DECIMAL(M,D),需指定总长度和小数位数
    • 日期时间:DATE、DATETIME、TIME
  • 隐式转换的两大坑 MySQL 会自动进行隐式类型转换(例如字符串和数字比较时,字符串会自动转成数字),但极易出问题:

    • 索引失效:对索引字段发生隐式转换时,索引会直接失效,查询性能骤降
    • 逻辑错误:非纯数字字符串转数字时,会从左截取到非数字字符为止,例如 '123abc' 会被转成 123,纯字母 'abc' 会被转成 0,极易引发数据错误。

    开发规范:尽量使用显式转换函数,保证逻辑可控。

  • 转换失败不报错 MySQL 的类型转换失败不会抛出异常,而是静默返回 0 或 NULL。例如 CAST('hello' AS SIGNED) 返回 0,CAST('非法日期' AS DATE) 返回 NULL,调试时需要特别注意。

  • CAST 与 CONVERT 选型建议

    • 日常类型转换优先用 CAST:属于标准 SQL 语法,兼容 Oracle、PostgreSQL 等所有数据库,迁移成本低
    • 仅在需要切换字符集时,使用 CONVERT(… USING …) 的专属语法
  • BINARY 性能问题 BINARY 虽然可以临时实现大小写敏感比对,但会导致索引失效,仅适合临时查询使用;长期业务需求建议直接修改字段的校对规则为 utf8mb4_bin

  • 5)流程控制函数

    流程控制函数用于在 SQL 中实现条件分支、空值兜底等逻辑判断,属于单行函数,逐行运算并返回结果,可替代简单的分支逻辑,无需在应用层二次处理

    分类函数 / 表达式语法格式功能说明示例与返回结果
    空值兜底类 IFNULL() IFNULL(expr1, expr2) 空值替换:若第一个表达式为 NULL,返回第二个值;否则返回第一个表达式本身 IFNULL(salary, 0) → 薪资为空时返回 0IFNULL(NULL, '默认值') → 默认值
    COALESCE() COALESCE(expr1, expr2, …) 返回参数列表中第一个非 NULL 的值;所有参数都为 NULL 则返回 NULL;支持任意多个参数,是通用的空值兜底函数 COALESCE(NULL, NULL, 0, 100) → 0
    NULLIF() NULLIF(expr1, expr2) 反向空值转换:若两个表达式的值相等,返回 NULL;不相等则返回第一个表达式的值 NULLIF(score, 0) → 分数为 0 时返回 NULLNULLIF(5, 3) → 5
    分支判断类 IF() IF(判断条件, 成立返回值, 不成立返回值) 单分支条件判断,等价于编程语言中的三元运算符 IF(age >= 18, '成年', '未成年')IF(salary > 5000, '高薪', '普通')
    CASE 表达式 WHEN …(简单 CASE) CASE 目标表达式<br> WHEN 值1 THEN 结果1<br> WHEN 值2 THEN 结果2<br> …<br> ELSE 默认值<br>END 对单个表达式做等值匹配,匹配到对应值则返回对应结果;都不匹配返回 ELSE 的默认值;省略 ELSE 则返回 NULL CASE gender<br> WHEN 1 THEN '男'<br> WHEN 2 THEN '女'<br> ELSE '未知'<br>END
    CASE WHEN …(搜索 CASE) CASE<br> WHEN 条件1 THEN 结果1<br> WHEN 条件2 THEN 结果2<br> …<br> ELSE 默认值<br>END 支持多条件、复杂范围判断,每个 WHEN 后可写独立的判断条件,是最灵活的分支写法 CASE<br> WHEN score >= 90 THEN '优秀'<br> WHEN score >= 60 THEN '及格'<br> ELSE '不及格'<br>END
    注意事项
  • CASE 必须以 END 结尾 忘记写 END 是最常见的语法错误;CASE 是一个表达式,最终会返回一个值,可以和普通字段一样设置别名。

  • 两种 CASE 的适用场景

    • 仅做等值匹配(如状态编码转中文含义),用简单 CASE,写法更简洁
    • 涉及范围判断、多字段组合判断,必须用搜索 CASE
  • 返回值类型尽量统一 同一个 CASE 中,所有 THEN 返回的数据类型建议保持一致,避免隐式类型转换导致的异常结果。

  • IFNULL 与 COALESCE 选型

    • 仅两个参数的简单空值兜底,用 IFNULL 写法更简短
    • 多个备选值、需要兼容标准 SQL,优先用 COALESCE
  • 避免过度嵌套 流程控制函数支持嵌套(如 IF 里套 IF),但嵌套过深会严重降低 SQL 可读性,复杂逻辑建议在应用层处理。

  • 注意与流程控制语句区分 这里的 IF()、CASE 都是单行函数 / 表达式,用在 SELECT、WHERE 等子句中;和存储过程 / 自定义函数里的 IF 语句、WHILE 循环不是同一个概念

  • 6)使用原则
  • 简单处理放数据库,复杂逻辑放应用层 函数适合做单行的格式转换、简单计算;复杂的多层嵌套判断、业务规则,建议放到 Java/Python 等应用代码里处理,SQL 可读性和维护性更好。

  • WHERE 条件中,不要对索引字段使用函数 比如 WHERE YEAR(create_time) = 2026 会导致 create_time 上的索引失效,一定要改写成范围查询:

    WHERE create_time >= '2026-01-01' AND create_time < '2027-01-01'

  • 警惕 NULL 传染 绝大多数函数,只要输入参数有 NULL,返回结果就是 NULL。比如 salary + NULL = NULL、CONCAT('姓名', NULL) = NULL。涉及可能为空的字段,一定要先用 IFNULL() 做兜底。

  • 不要过度嵌套函数 多层嵌套的函数会让 SQL 很难读懂和维护,能简化就简化,能在应用层处理就不要堆在 SQL 里

  • (2)多行函数/聚合函数

    多行函数也叫组函数、聚合函数,作用是对一组数据行进行汇总运算,每组最终只返回一个计算结果,常与 GROUP BY 分组子句搭配,实现维度统计、汇总计算等业务需求

    与单行函数核心差异:单行函数逐行计算、一行对应一个结果;多行函数按组聚合、一组对应一个结果

    分类函数名称语法格式功能说明示例与返回结果
    计数统计 COUNT(*) COUNT(*) 统计结果集的总行数,不会忽略 NULL 值行 COUNT(*) → 统计员工总人数
    COUNT(字段名) COUNT(column) 统计指定字段的非空行数,自动忽略值为 NULL 的行 COUNT(bonus) → 统计有奖金的员工人数
    COUNT(DISTINCT 字段名) COUNT(DISTINCT column) 统计指定字段去重后的非空行数 COUNT(DISTINCT dept_id) → 统计有员工的部门数量
    数值计算 SUM() SUM(column) 对指定数值字段求和,自动忽略 NULL 值 SUM(salary) → 计算全公司薪资总和
    AVG() AVG(column) 计算指定数值字段的平均值,自动忽略 NULL 值 AVG(salary) → 计算员工平均薪资
    极值统计 MAX() MAX(column) 返回指定字段的最大值,支持数值、日期、字符串类型,自动忽略 NULL MAX(salary) → 查询全公司最高薪资
    MIN() MIN(column) 返回指定字段的最小值,支持数值、日期、字符串类型,自动忽略 NULL MIN(create_time) → 查询最早的入职时间

    核心搭配语法
    1. GROUP BY 分组

    当需要按维度拆分统计(如按部门、按岗位、按日期)时,使用 GROUP BY 将数据划分为多个组,聚合函数会针对每个组分别计算。

    — 统计每个部门的员工人数、平均薪资、最高薪资
    SELECT
    dept_id,
    COUNT(*) AS 员工人数,
    AVG(salary) AS 平均薪资,
    MAX(salary) AS 最高薪资
    FROM emp
    GROUP BY dept_id;

    语法规则:SELECT 子句中,除聚合函数外的普通字段,必须同时出现在 GROUP BY 子句中,否则会出现逻辑错误或非预期结果。

    2. HAVING 分组后筛选

    用于对分组聚合后的结果做条件过滤,必须与 GROUP BY 配合使用。

    — 筛选出平均薪资大于 8000 的部门
    SELECT
    dept_id,
    AVG(salary) AS 平均薪资
    FROM emp
    GROUP BY dept_id
    HAVING AVG(salary) > 8000;

    WHERE 与 HAVING 的核心区别:

    • WHERE:分组聚合之前筛选原始数据行,不能使用聚合函数作为条件
    • HAVING:分组聚合之后筛选分组结果,条件只能是分组字段或聚合函数
    • 执行顺序:FROM → JOIN → WHERE → GROUP BY → 聚合计算 → HAVING → ORDER BY → LIMIT

    注意事项
  • NULL 值自动忽略 所有聚合函数都会自动跳过值为 NULL 的行,不参与计算。例如 AVG(bonus) 仅计算有奖金的员工,NULL 行不会计入分母;若需将 NULL 按 0 计算,需先用 IFNULL(bonus, 0) 做兜底处理。

  • COUNT (*) 与 COUNT (字段) 的差异

    • COUNT(*):统计总行数,包含 NULL 行,性能最优,是通用计数写法
    • COUNT(字段):仅统计该字段非空的行数
    • 无特殊空值过滤需求时,优先使用 COUNT(*)。
  • WHERE 中禁止使用聚合函数 聚合函数的计算晚于 WHERE 执行,因此 WHERE 子句中不能写聚合函数条件;分组后的筛选必须使用 HAVING。

  • 支持多字段分组 GROUP BY 可指定多个字段实现组合维度统计,例如 GROUP BY dept_id, job 表示按「部门 + 岗位」的组合维度分组。

  • 去重聚合 聚合函数可搭配 DISTINCT 实现去重统计,例如 COUNT(DISTINCT user_id) 统计去重后的用户数,避免重复数据干扰统计结果。

  • 全局聚合规则 不写 GROUP BY 时,整张表会被默认为一个组,最终只返回一行聚合结果,适用于全表整体统计的场景。

  • 4.用户管理

    MySQL是一个多用户的数据库系统,按照权限,用户可以分为两种:root(超级管理员)用户和由root用户创建的普通用户

    (1)创建用户

    CREATE USER username IDENTIFIED BY 'password';

    示例:创建一个允许任意主机登录的普通用户 test_user

    CREATE USER 'test_user'@'%' IDENTIFIED BY '123456';

    说明:用户名后需搭配主机地址,格式为用户名@主机地址;省略主机地址时,默认值为%。

    (2)查看用户

    SELECT USER,HOST FROM mysql.user;

    在MySQL数据库安装完后会有一个默认的表叫做mysql,这里面有一个表叫user记录了所有的用户,我们查询的是这个表中的两个列,USER是用户名,而HOST则是用户权限

    • localhost:仅允许从数据库本机登录
    • 127.0.0.1:通过TCP/IP协议在本机链接
    • ::1:兼容支持ipv6,表示同ipv4的本机访问
    • %:允许从任意远程主机登录
    • 指定 IP 地址:仅允许从对应 IP 的主机登录

    (3)修改用户

    1)修改用户密码

    ALTER USER 用户名@主机地址 IDENTIFIED BY '新密码';

    示例:修改 test_user 的登录密码

    ALTER USER 'test_user'@'%' IDENTIFIED BY 'new_password_666';

    说明:ALTER USER是 MySQL 官方推荐的标准改密语法,兼容性与安全性最优。

    2)修改用户名与登录主机

    RENAME USER 旧用户名@旧主机地址 TO 新用户名@新主机地址;

    示例:将用户的登录范围从任意主机限制为仅本地登录

    RENAME USER 'test_user'@'%' TO 'test_user'@'localhost';

    (4)删除用户 

    DROP USER 用户名@主机地址;

    示例:删除 test_user 用户

    DROP USER 'test_user'@'%';

    说明:MySQL 以「用户名 + 主机地址」作为用户唯一标识,删除时必须同时指定两者才能精准匹配;用户删除后,其名下所有权限会被同步清除。

    (5)权限管理(DCL)

    新创建的用户默认没有任何操作权限,仅能登录数据库,无法读写数据;需要由管理员账号授予对应权限后,才能执行对应的数据库操作。权限按粒度从大到小可分为全局权限、库级权限、表级权限、列级权限。

    1)常用权限说明

    上面有表,这是一部分

    • ALL PRIVILEGES:除授权外的所有操作权限
    • SELECT:查询数据权限
    • INSERT:插入数据权限
    • UPDATE:修改数据权限
    • DELETE:删除数据权限
    • CREATE:创建数据库、数据表权限
    • DROP:删除数据库、数据表权限
    2)授予权限

    GRANT 权限列表 ON 数据库名.表名 TO 用户名@主机地址;

    示例:

    — 给用户授予 test 库下所有表的查询、插入、修改权限
    GRANT SELECT,INSERT,UPDATE ON test.* TO 'test_user'@'%';

    — 给用户授予所有库所有表的全部权限(超级管理员权限,生产环境谨慎使用)
    GRANT ALL PRIVILEGES ON *.* TO 'admin_user'@'%';

    3)查看用户权限

    SHOW GRANTS FOR 用户名@主机地址;

    示例:

    SHOW GRANTS FOR 'test_user'@'%';

    4)撤销权限

    REVOKE 权限列表 ON 数据库名.表名 FROM 用户名@主机地址;

    示例:

    — 撤销用户对 test 库的删除数据权限
    REVOKE DELETE ON test.* FROM 'test_user'@'%';

    (6)刷新权限

    FLUSH PRIVILEGES;

    说明:如果通过直接修改mysql.user等系统表的方式操作用户与权限,需要执行该命令让配置立即生效;通过CREATE USER、GRANT、REVOKE等标准 SQL 操作时,MySQL 会自动刷新权限,无需手动执行。

    (7)使用注意事项

    1)用户唯一标识:

    MySQL 中「用户名 + 主机地址」共同组成一个完整用户,同名不同主机视为两个独立账号,权限互不影响。

    2)最小权限原则:

    仅授予业务必需的最小权限,禁止随意开放全局ALL PRIVILEGES权限,降低数据安全风险。

    3)访问范围管控:

    生产环境尽量避免使用%开放全主机登录,应限制为指定业务 IP 访问。

    4)root 账号规范:

    root 超级管理员账号仅用于本地运维配置,禁止直接用于业务系统连接数据库。

    (后续可能会更新)

    赞(0)
    未经允许不得转载:171主机测评 » MySql基础夯实:从配置到掌握(看这一篇就够了!)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址