1. 装好一个能用的MySQL,为什么比想象中麻烦
很多人觉得MySQL安装是个“下一步下一步”的事,真正动手才发现,热搜词里“mysql安装教程”、“mysql安装配置教程”、“windows安装mysql”常年霸榜,不是没有道理的。我见过太多人在安装这一步就卡住,最后连“连接不上数据库”“启动服务报错”是环境问题还是配置问题都分不清。
1.1 Windows安装:最容易卡住的三个环节
Windows下安装MySQL,最常见的坑集中在三个地方。
第一个是安装类型选择。MySQL Installer提供Developer Default、Server only、Client only等选项,很多人直接默认Developer Default,结果把Visual Studio组件、MySQL for Excel、Connector全家桶全装上了,机器配置一般的直接卡死。我建议普通学习环境只选Server only,后面需要什么再单独补。
第二个是Check Requirements卡住不动。热搜里“win10 mysql安装到check requirements”就是这么来的。这一步本质是检查系统依赖,比如Visual C++ Redistributable、.NET Framework等。如果卡在这里超过十分钟,大概率不是网络问题,而是系统里缺少某个运行库,或者Windows Installer服务异常。这时候最快的办法是关掉安装器,去微软官网手动装好Visual C++ 2015-2022 Redistributable x64,再重新跑安装程序,基本都能过。
第三个是初始化类型和root密码设置。MySQL 8.0的安装向导会让你选Authentication Method,默认第一个是Caching SHA-2 Password,这个加密方式更安全,但很多老版本客户端和驱动不认它。如果后面用Navicat或某些老项目连接时报认证协议错误,根源大概率在这里。第二个选项是Legacy Authentication,兼容MySQL 5.x的老客户端。个人复习环境我建议先选第二个,把兼容性放在第一位,等后面理解了认证机制再切回新的。
安装完成后,一定要确认MySQL服务是否真的起来了。打开服务管理器(Win+R输入services.msc),找MySQL服务,确认状态是“正在运行”。这里有个小技巧:如果服务启动失败,先看Windows事件查看器里的错误日志,大多数情况下是my.ini里的datadir路径有问题,或者端口3306被占用。查看端口占用用netstat -ano | findstr 3306,找到占用进程直接结束,或者修改my.ini里的port值。
1.2 Docker方式安装:复习效率最高的方案
如果你不想把宿主机搞乱,或者需要在多个MySQL版本之间切换复习,Docker是更优解。我自己的习惯是:宿主机上不装任何MySQL,全部用容器跑。
启动一个MySQL 8.0容器只需要一条命令:
bash复制docker run -d \
--name mysql8 \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai \
-v /data/mysql8/conf:/etc/mysql/conf.d \
-v /data/mysql8/data:/var/lib/mysql \
mysql:8.0
解释一下几个关键参数:-e MYSQL_ROOT_PASSWORD指定root密码,TZ设置时区避免时间差八小时,两个-v分别挂载配置目录和数据目录。数据目录挂载出来非常重要,否则容器删掉数据就全没了。
用Docker的好处不只是干净,还有一个隐藏优势:容器删掉重建,几秒钟就能回到干净环境。复习存储过程、事务隔离级别这些需要反复造数据、清数据的操作时,这个特性非常实用。
1.3 安装启动服务报错的通用排查链路
“安装mysql启动服务报错”这个问题,我复盘过很多次,其实有个固定的排查链路,按顺序走一遍基本能定位:
-
查看错误日志。MySQL的数据目录下有个
*.err文件,里面记录了启动时的详细报错。Windows一般在C:\ProgramData\MySQL\MySQL Server 8.0\Data\下,Docker容器里在/var/log/mysql/下。日志里提示什么就解决什么,比瞎猜强一百倍。 -
检查配置文件语法。
my.ini或my.cnf里的每一项配置,写错一个单词、多一个空格,都可能让服务起不来。可以先执行mysqld --validate-config验证配置是否正确。 -
确认数据目录权限。这个问题在Docker和Linux环境最常见。容器启动时指定的
/var/lib/mysql目录如果权限不对,MySQL进程根本没有写入权限,自然起不来。加上-e MYSQL_ROOT_PASSWORD之前,先确认挂载目录的属主是UID 999(MySQL镜像默认用户)。 -
端口占用。这个不用多说,3306被其他程序占了,MySQL服务会直接退出。
-
最后再考虑系统级问题,比如内存不足、磁盘满等,用
dmesg或Windows事件查看器确认。
安装是基础,但很多人恰恰倒在基础上。我的建议是:至少要亲手装过两次MySQL,一次Windows原生安装,一次Docker安装,这样才能真正理解MySQL的目录结构、配置加载顺序、服务管理方式,这些后面排错都离不开。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 日常CRUD里最容易翻车的几个点
数据库连上了,服务跑起来了,接下来就是写SQL。热搜词里“mysql update语法”、“mysql排序”、“mysql常用函数”、“mysql中int+5”这几个,都属于日常CRUD但高阶版本。很多错误写法在数据量小的时候没问题,一旦数据量上来,就是事故现场。
2.1 UPDATE语法:不加WHERE条件的代价
MySQL的UPDATE基本语法是:
sql复制UPDATE table_name
SET column1 = value1, column2 = value2
WHERE condition;
看起来很简单,但实际使用中至少有三种翻车方式。
第一种,忘记WHERE子句。这个最致命,一条SQL下去整张表全被更新了。我见过不止一次,有人跑完才发现表里的数据全变成同一个值。这种错误在开发环境顶多重来,在生产环境就是事故。重要UPDATE前先SELECT确认影响行数,是个好习惯。或者用LIMIT限制更新条数。MySQL支持UPDATE ... LIMIT 1这种写法,可以防止一次误更新过多数据。
第二种,WHERE条件写得不对。常见的是用=去匹配可空的列,比如WHERE name = NULL,这种写法永远匹配不到任何行,因为NULL不能用=比较,必须用IS NULL。还有字符集不一致导致的匹配问题,比如一个字段是utf8mb4,另一个是latin1,=比较时可能出现查不到或误查的情况。
第三种,UPDATE多表连接时踩坑。MySQL支持UPDATE table1 JOIN table2 ON ... SET ...这种多表更新语法,但ON条件写得太宽,会导致更新范围超出预期。多表UPDATE前,先把JOIN结果SELECT出来看一下,确认范围再动手。
2.2 排序:不只是ORDER BY那么简单
ORDER BY是最基础的排序语法,但实际场景中往往没那么简单。
先看基础逻辑:
sql复制SELECT * FROM employees ORDER BY salary DESC;
SELECT * FROM employees ORDER BY department_id ASC, salary DESC;
第一个按salary降序,第二个先按部门升序、同部门内按工资降序。这里有个容易忽略的细节:多列排序时,只有前一列的值相同,才会用后一列决定顺序。
排序里坑最多的场景是中文排序。MySQL默认的排序规则是utf8mb4_general_ci,中文按Unicode编码排序,结果往往不符合拼音或笔画习惯。如果需要按拼音排序,要么把字段的排序规则改成utf8mb4_zh_0900_as_cs,要么用ORDER BY CONVERT(name USING gbk)这样的转换方式。不过在MySQL 8.0里,更推荐直接建表时用utf8mb4_zh_0900_as_cs排序规则,一劳永逸。
另一个坑是NULL值的排序位置。在MySQL中,ORDER BY column ASC时,NULL值默认排在最前面;ORDER BY column DESC时,NULL值排在最后面。这个行为和其他数据库可能不一样,写代码时如果对NULL有特殊要求,必须显式处理。比如要把NULL放在最后,可以这样写:
sql复制SELECT * FROM employees ORDER BY ISNULL(salary), salary ASC;
2.3 常用函数:日期、字符串、聚合的复习清单
MySQL内置函数非常多,但日常开发真正高频使用的,其实就那一批。这里列一个直接可用的清单。
日期时间函数:
NOW():当前日期时间CURDATE():当前日期DATE_FORMAT(date, '%Y-%m-%d'):格式化日期DATEDIFF(date1, date2):两个日期差几天DATE_ADD(date, INTERVAL 1 DAY):日期加减
复习时特别推荐把DATE_FORMAT的格式符过一遍,%Y四位年份、%y两位年份、%m月份、%d日、%H24小时制、%i分钟、%s秒,这几个是查询报表时天天用的。
字符串函数:
CONCAT(str1, str2):拼接字符串SUBSTRING(str, pos, len):截取字符串REPLACE(str, from_str, to_str):替换字符串UPPER(str)/LOWER(str):大小写转换LENGTH(str):字节长度,注意utf8mb4下一个中文占3字节- `CHAR_
