MySQL这个坑,我替你先踩了。很多新手第一次接触它,装个环境就被吓退,好不容易装上,一敲命令又全是报错。这篇东西就是写给零基础朋友的,我会把从下载安装、配置环境变量,到建库建表、增删改查、备份恢复这一整套流程,用最直白的话讲清楚。你不需要懂编程,只要会点鼠标、能复制粘贴,看完就能上手操作。
1. 零基础学MySQL之前,先搞懂这几件底层事
1.1 数据库、表、字段到底是什么关系
很多人一开始就被“数据库”这个名字唬住了。其实你可以把MySQL想象成一个超级大的Excel文件柜。MySQL这个软件本身是一个“文件柜管理工具”,里面可以放很多个“抽屉”,每个抽屉就叫一个数据库(Database)。每个抽屉里面又可以放很多张“表格”,这就是数据表(Table)。每张表格由“列”(字段)和“行”(记录)组成。
举个例子:你要做一个学生管理系统。你可以先建一个叫school的数据库,然后在里面建一张student表。这张表有id、name、age、score这几列,每一行就是一个学生的具体信息。用SQL语句表达就是:
sql复制CREATE DATABASE school;
USE school;
CREATE TABLE student (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(50),
age INT,
score DECIMAL(5,2)
);
这套逻辑是所有关系型数据库通用的,学会了MySQL,以后碰PostgreSQL、SQL Server,思路完全一样,只是个别语法细节不同。
1.2 SQL语句的四大门派,先记个大概
SQL(Structured Query Language)是操作数据库的标准语言,你不需要背几百条命令,核心就四大类:
- DDL(数据定义语言):负责建库、建表、改表结构,比如
CREATE、ALTER、DROP - DML(数据操作语言):负责对数据干活,比如
INSERT(插入)、DELETE(删除)、UPDATE(修改) - DQL(数据查询语言):最常用,代表就是
SELECT,查询数据全靠它 - DCL(数据控制语言):管权限的,比如
GRANT给用户授权、REVOKE收回权限
新手期90%的时间都在跟DML和DQL打交道。碰到不认识的命令,先查它属于哪一类,理解就快多了。
1.3 版本选择:别一上来就装最新版
MySQL官方版本迭代很快,现在主流是8.0系列,5.7也还有大量存量用户在跑。我给你的建议是:个人学习直接装8.0以上版本,因为8.0在性能、默认字符集(utf8mb4)、窗口函数等方面都比5.7强很多。尽量不要去装5.6之类的老古董了,很多语法和配置跟现在的主流教程都对不上。
还有个小细节:MySQL有个分支叫MariaDB,它是MySQL被收购后分叉出来的。有些Linux教程会让你用yum install mariadb-server,这个虽然命令跟MySQL几乎一样,但毕竟不是同一个东西。如果你是想学MySQL,记得装的是mysql-server,别装成MariaDB了,不然以后看官方文档会混乱。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境搭建:MySQL安装配置全流程实录
2.1 Windows下安装MySQL 8.0详细步骤
去MySQL官网下载(mysql.com),点Downloads,选MySQL Community Server,这是免费的社区版。下载时注意选“Windows (x86, 64-bit), ZIP Archive”这个格式,它解压就能用,比那个MSI安装包更灵活、更好控制。当然,如果你觉得MSI图形化安装更省事也行,就是它有时候会在系统里装一些附带服务,后期想卸载比较麻烦。
ZIP包安装流程我实测过很多次,完整步骤如下:
- 解压到指定目录,比如
D:\mysql-8.0.36-winx64。别把路径带中文和空格,后面很多工具会出毛病。 - 在这个目录下新建一个
my.ini配置文件(注意扩展名,不是my.txt),写入最基础的内容:
ini复制[mysqld]
basedir=D:/mysql-8.0.36-winx64
datadir=D:/mysql-8.0.36-winx64/data
port=3306
character-set-server=utf8mb4
default-storage-engine=INNODB
[client]
default-character-set=utf8mb4
注意:这里有个大坑。很多教程会让你手动建一个空的
data文件夹,其实不用。如果你提前建了空的data目录,后面执行初始化命令反而可能报错。让mysqld自己生成就好。
- 以管理员身份打开命令行(cmd),先进入MySQL的bin目录:
bash复制cd D:\mysql-8.0.36-winx64\bin
- 执行初始化命令,这一步是生成系统数据库和root账号,千万不能跳过:
bash复制mysqld --initialize-insecure
这里我故意用initialize-insecure而不是--initialize,区别是:insecure模式生成的root账号是空密码,方便你第一次登录;而--initialize会生成一个随机密码,存在data目录下的xxx.err日志文件里,新手找半天找不到,白白卡住。
- 安装Windows服务并启动:
bash复制mysqld --install
net start mysql
- 登录测试:
bash复制mysql -u root -p
提示输密码时直接回车(因为空密码)。
2.2 配置环境变量:让你的命令随处可用
这步很多人觉得无所谓,实际影响非常大。如果不配环境变量,你每次想用mysql命令,都得先cd到MySQL的bin目录下,烦死了。配置方法:右键“此电脑” → 属性 → 高级系统设置 → 环境变量 → 在“系统变量”里找到Path,点编辑,新建一条,填入你的MySQL bin路径(比如D:\mysql-8.0.36-winx64\bin)。之后重新打开命令行,直接敲mysql -u root -p就能进。
要提醒你的是:改完环境变量,已经打开的命令行窗口不会生效,必须新开一个。很多人改完了,在旧窗口里敲命令还是提示“不是内部或外部命令”,就以为没配好,其实只是没重开窗口而已。
2.3 用Docker装MySQL是不是更好的选择
如果你电脑上有Docker,或者你愿意装一个Docker Desktop,那用容器跑MySQL确实省心很多,尤其适合不想在自己系统里装一堆依赖的朋友。一条命令就能起一个实例:
bash复制docker run --name mysql-study \
-e MYSQL_ROOT_PASSWORD=123456 \
-p 3306:3306 \
-d mysql:8.0
启动后,进入容器内操作:
bash复制docker exec -it mysql-study mysql -u root -p
但这里有个必须提前知道的坑:容器默认的数据存储是在容器内部,一旦容器被删除,数据全没了。所以挂载数据目录是必须的,否则你辛辛苦苦造的数据可能一次docker rm就清零了。下面是带数据挂载的版本:
bash复制docker run --name mysql-study \
-v /my/own/datadir:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
-p 3306:3306 \
-d mysql:8.0
Docker方案适合喜欢折腾、或者电脑环境特别乱(装过很多版本MySQL,端口冲突)的朋友。相对而言,Windows原生安装更适合想一门心思搞懂MySQL本身原理的人,两种路线没有绝对优劣,看你自己取舍。
3. 建库建表实战:从零搭建一个完整的表结构
3.1 登录MySQL的几种姿势
环境装好了,第一件事就是登录。我们的MySQL服务跑在3306端口。登录命令标准版是这样的:
bash复制mysql -h localhost -P 3306 -u root -p
-h指定主机,-P指定端口(大写P),-u用户名,-p表示需要密码。如果连接本机,-h localhost可以省略,直接mysql -u root -p。
登录之后你会看到mysql>这个提示符。看到它,你就成功进入了MySQL的世界。先不要急着写业务,用这几条命令探探路:
sql复制-- 查看当前MySQL版本
SELECT VERSION();
-- 查看当前有哪些数据库(注意最后要加分号)
SHOW DATABASES;
新手最容易犯的错:敲完命令不打分号。MySQL把所有以分号结尾的内容才视为一条完整语句。不打分号就回车,它会显示一个
->提示你继续输入。这时候补个分号再回车就行,不用慌。
3.2 创建第一个数据库:CREATE DATABASE细节
用SQL语句创建一个数据库:
sql复制CREATE DATABASE IF NOT EXISTS school
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;
IF NOT EXISTS是保险措施,如果school数据库已存在,不会报错。utf8mb4这个字符集是专门坑过无数人的点:很多老项目用utf8,结果插入emoji表情或者生僻字的时候就报错,因为MySQL的utf8最多只能存3字节,而表情符号是4字节。utf8mb4才是真正的“全量UTF-8”。从8.0开始,MySQL默认就是utf8mb4,但你自己建库的时候最好还是显式加上,养成好习惯。
COLLATE是排序规则,utf8mb4_unicode_ci表示按Unicode编码排序且不区分大小写(_ci就是case insensitive)。字符集和排序规则决定了字符串怎么存、怎么比大小、怎么排序,这些在后期数据量大了以后影响非常大。
3.3 设计一张规范的student表:字段类型与约束选择
选定数据库:
sql复制USE school;
接下来建表。这是整个数据库操作中最重要的环节,表结构设计不好,后面改起来痛不欲生。下面是一个学生表的完整设计:
sql复制CREATE TABLE student (
id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',
stu_no VARCHAR(20) NOT NULL UNIQUE COMMENT '学号',
name VARCHAR(50) NOT NULL COMMENT '姓名',
gender ENUM('男','女') DEFAULT '男' COMMENT '性别',
age TINYINT UNSIGNED DEFAULT 18 COMMENT '年龄',
birth_date DATE COMMENT '出生日期',
phone VARCHAR(11) COMMENT '手机号',
email VARCHAR(100) COMMENT '邮箱',
score DECIMAL(5,2) DEFAULT 0.00 COMMENT '综合成绩',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生信息表';
我来逐条解释为什么这么设计,这些都是实际开发中沉淀出来的经验。
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT:主键用自增整数。UNSIGNED表示无符号,只存非负数,这样可用的ID范围直接翻倍。AUTO_INCREMENT让数据库自动生成不重复的递增序号,你插入数据时不用管这个字段。stu_no VARCHAR(20) NOT NULL UNIQUE:学号用字符串类型而不是整数,因为学号前面往往有0,比如20250001,用整数会自动去掉前缀0。UNIQUE约束保证学号不重复。gender ENUM('男','女'):枚举类型可以限定字段只能取指定值。但注意,ENUM后期如果想加一个值,需要改表结构,灵活性差。如果项目很正式,建议gender存TINYINT(0保密 1男 2女),这样更规范。这里用ENUM是为了教学直观。score DECIMAL(5,2):成绩要精确到小数点后两位,必须用DECIMAL,不能使用FLOAT或DOUBLE。原因很简单:浮点数在计算机里是近似存储,0.1+0.2可能等于0.30000000000000004。跟钱、分数相关的数据,一点都不能差。create_time DATETIME DEFAULT CURRENT_TIMESTAMP:插入时自动填当前时间。update_time加ON UPDATE CURRENT_TIMESTAMP,就是只要这一行被更新,时间会自动刷新。这两个字段是通用设计,几乎所有业务表里都该加。
3.4 修改表结构:ALTER TABLE的日常操作
建好的表很少能一步到位,业务一变就要改结构。要加一列“班级名称”,就这么写:
sql复制ALTER TABLE student ADD COLUMN class_name VARCHAR(50) COMMENT '班级' AFTER name;
AFTER name表示新列加在name字段后面。不加的话默认加在最后一列。
要修改字段类型:
sql复制ALTER TABLE student MODIFY COLUMN phone VARCHAR(20);
只是改了字段类型,COMMENT等属性会丢失,还得重新写上,这个坑我也踩过。
要改字段名:
sql复制ALTER TABLE student CHANGE COLUMN class_name class_no VARCHAR(30);
CHANGE比MODIFY多一个旧名和新名的参数。日常开发中,如果只是改字段属性用MODIFY,要改字段名才用CHANGE。
大表操作提醒:如果表里已经存了几百万行数据,执行
ALTER TABLE可能会锁住整张表,导致线上业务卡顿。在生产环境操作前,最好先评估数据量,或者用pt-osc之类的工具平滑变更。新手可能遇不到这种场景,但应该知道有这个风险。
4. 数据操作实战:增删改查与条件筛选
4.1 插入数据:INSERT语句几种写法对照
表建好了,开始往里灌数据。先看看单条插入的写法:
sql复制INSERT INTO student (stu_no, name, gender, age, class_name, score)
VALUES ('2025001', '张小明', '男', 19, '计算机2401班', 88.50);
需要特别注意的是字段列表和VALUES数量、顺序必须完全对应。如果偷懒省略字段列表,直接INSERT INTO student VALUES (……),就得把所有字段按建表顺序写全,包括自增的id都可以不写,但要占个空位(写DEFAULT也行)。实际开发中我强烈建议你明确写字段列表,因为表结构后期很可能会加字段,省略写法的SQL到时候全报错。
批量插入是效率利器。一次插入10条和循环插入10次,性能差距是数量级的。写法如下:
sql复制INSERT INTO student (stu_no, name, gender, age, class_name, score) VALUES
('2025002', '李小红', '女', 20, '计算机2401班', 92.00),
('2025003', '王强', '男', 19, '软件2402班', 76.50),
('2025004', '赵敏', '女', 18, '人工智能2401班', 95.00);
4.2 查询数据:SELECT的进阶段位
查询是SQL中使用频率最高的操作。基础查询很简单:
sql复制-- 查询所有学生的所有字段(千万别在正式环境这样干,数据量大会卡死)
SELECT * FROM student;
-- 只看学号和姓名
SELECT stu_no, name FROM student;
-- 给查询结果起别名(显示更友好)
SELECT stu_no AS '学号', name AS '姓名' FROM student;
条件筛选是查询的灵魂。WHERE后面加条件:
sql复制-- 查询成绩大于等于90分的学生
SELECT name, score FROM student WHERE score >= 90;
-- 查询计算机2401班的女同学
SELECT name, gender, class_name FROM student
WHERE class_name = '计算机2401班' AND gender = '女';
-- 查询班级是软件2402班 或者 分数小于80的学生
SELECT name, class_name, score FROM student
WHERE class_name = '软件2402班' OR score < 80;
这里有经典的AND、OR优先级陷阱:AND比OR的优先级高。如果你写WHERE class_name = '软件2402班' OR class_name = '计算机2401班' AND score > 90,它实际执行的是:先过滤出计算机2401班里分数大于90的,再并上软件2402班全部学生。如果要的是“软件2402班或计算机2401班中分数大于90的学生”,必须加括号:
sql复制SELECT name, class_name, score FROM student
WHERE (class_name = '软件2402班' OR class_name = '计算机2401班') AND score > 90;
排序这块,ORDER BY默认升序ASC,降序用DESC:
sql复制-- 按成绩从高到低排序,如果成绩相同按年龄从小到大
SELECT name, score, age FROM student
ORDER BY score DESC, age ASC;
还有一个让很多人惊喜的运算符IN,匹配指定列表:
sql复制SELECT name, class_name FROM student
WHERE class_name IN ('计算机2401班', '软件2402班');
模糊查询用LIKE配合%:
sql复制-- 查所有姓王的同学(%表示任意长度字符串)
SELECT * FROM student WHERE name LIKE '王%';
-- 查名字里带“小”的同学
SELECT * FROM student WHERE name LIKE '%小%';
%在头部,相当于全表扫描,数据量大了会非常慢,但入门阶段先不管优化,知道有这个现象就行。
4.3 更新与删除:两个必须手滑防护的操作
更新数据用UPDATE,它的标准带条件写法是:
sql复制UPDATE student SET score = 90.5, update_time = NOW() WHERE id = 1;
这里再强调一次:如果忘了加WHERE,后果就是全表所有学生的成绩都被改成90.5。新手阶段务必养成先SELECT确认再UPDATE的习惯,线上操作之前,先查出来看一眼影响范围,再执行更新。
删除同理:
sql复制-- 删除学号为2025004的学生
DELETE FROM student WHERE stu_no = '2025004';
-- 如果真删全表,写法是TRUNCATE;它比DELETE快很多
TRUNCATE TABLE student;
DELETE FROM student不带WHERE会一行一行删,效率低且自增ID不会重置;TRUNCATE直接重建表,速度飞快,自增ID从头开始。两招全表清空,但效果不一样,按需选择。
逻辑删除也是个重要概念:业务系统基本不会真正把数据物理删掉,而是加一个is_deleted字段,删除时把它置为1。这样数据可以追溯、可以恢复。这也是为什么很多表的字段里会有一列is_deleted TINYINT DEFAULT 0。
4.4 聚合统计与分组:GROUP BY和常见函数
查询里的“统计”需求很常见。班上一共有多少人?班级平均分多少?看这几段:
sql复制-- 统计总人数
SELECT COUNT(*) AS total FROM student;
-- 统计平均分、最高分、最低分
SELECT AVG(score) AS avg_score, MAX(score) AS max_score, MIN(score) AS min_score FROM student;
-- 按班级分组统计人数和平均分
SELECT class_name, COUNT(*) AS cnt, AVG(score) AS avg_score
FROM student
GROUP BY class_name;
GROUP BY class_name把相同班级的行聚合到一组,然后针对每一组做统计计算。这里有个SQL语法规则非常容易弄错:用了GROUP BY之后,SELECT后面出现的字段,要么是分组字段本身,要么是聚合函数(COUNT、SUM、AVG、MAX、MIN等),不能随便把非分组字段放进来,否则在MySQL的ONLY_FULL_GROUP_BY模式下直接报错。
如果想对分组后的结果再做过滤,不能用WHERE,要用HAVING:
sql复制-- 查出平均分大于85的班级
SELECT class_name, AVG(score) AS avg_score
FROM student
GROUP BY class_name
HAVING avg_score > 85;
WHERE是分组前过滤行,HAVING是分组后过滤组,执行的先后顺序不一样,理解这个就能分清两者使用场景。
还有一个实用场景经常把我朋友绕晕,就是行转列。比如要把每个班男女生的平均分展示成一行:班级、男平均分、女平均分
sql复制SELECT
class_name,
MAX(CASE WHEN gender='男' THEN score END) AS male_score,
MAX(CASE WHEN gender='女' THEN score END) AS female_score
FROM student
GROUP BY class_name;
这里用CASE WHEN把行里的性别转成不同的列,再用MAX取数(其实是配合分组去重)。实际业务中做报表,这种“行转列”操作非常常见,逻辑可以收藏起来以后参考。
5. 服务运维与安全:每天都要做的基本功
5.1 备份与恢复:mysqldump使用指南
数据库最怕的就是数据丢失。哪怕只是本机学习,也要养成定期备份的好习惯。MySQL自带的备份工具叫mysqldump,它不在mysql交互环境里执行,而是直接在命令行敲:
bash复制mysqldump -u root -p school > school_backup.sql
这句话把school整个数据库的所有表结构和数据导出了一个SQL文件。想恢复,回到mysql命令行:
bash复制mysql -u root -p school < school_backup.sql
这里有个坑:恢复之前,你得确保school这个数据库已存在。如果不存在,要先CREATE DATABASE school,再use进去执行。如果想连库带建库语句一起备份,可以加一个参数:
bash复制mysqldump -u root -p --databases school > school_with_create.sql
这样恢复的时候就不用手动建库了,因为备份文件里包含了CREATE DATABASE IF NOT EXISTS。如果是整个实例的数据全备份,用--all-databases。
生产环境数据量大的备份就是一门艺术了,涉及全量加增量、binlog日志等策略。但小白阶段,先把mysqldump的这套完整流程吃透,以后去哪儿都够用。
5.2 用户与权限:别动不动就用root
很多新手从头到尾只用root账号,自己学习倒无所谓,但如果以后去了公司还这样干,会被运维骂的。正确做法是给每个应用创建独立账号,只授最小权限。
sql复制-- 创建用户,指定密码
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'your_password';
-- 授予app_user对school库所有表的所有权限
GRANT ALL PRIVILEGES ON school.* TO 'app_user'@'localhost';
-- 只授予查询权限,不给写权限
GRANT SELECT ON school.* TO 'readonly_user'@'localhost';
用户名后面的@'localhost'限制登录来源。写成'app_user'@'%'表示允许从任何主机连过来,只有远程连接需求时才需要这样设置。授权之后记得执行:
sql复制FLUSH PRIVILEGES;
刷新权限表,让修改立即生效。查看某个用户的权限:
sql复制SHOW GRANTS FOR 'app_user'@'localhost';
5.3 MySQL忘记密码怎么办:重置root密码实操
忘记root密码是每个MySQL使用者都会遇到的事,别问我怎么知道的。Windows环境下的处理思路是:跳过权限验证启动MySQL,然后把密码改掉。
第一步,停止MySQL服务。在管理员命令行里执行:
bash复制net stop mysql
第二步,用skip-grant-tables方式启动:
bash复制mysqld --skip-grant-tables
注意,这个命令是前台运行模式,这个命令行窗口会一直被占用,先不要管它。另外打开一个新的命令行窗口,不用密码直接进:
bash复制mysql -u root
进去以后先刷新权限:
sql复制FLUSH PRIVILEGES;
然后再改密码。MySQL 8.0的改密码语法和5.7不一样,8.0要用:
sql复制ALTER USER 'root'@'localhost' IDENTIFIED BY '新密码';
改完之后exit退出。然后回到第一个窗口按Ctrl+C停掉mysqld,再正常启动服务:
bash复制net start mysql
用新密码登录就能进去了。
提醒:
--skip-grant-tables模式下,任何人都能无密码登录你的数据库,极度危险。只能在本地操作、改完立刻重启恢复正常模式,千万不要在这个状态下让MySQL长时间对外提供连接。
5.4 用Navicat还是命令行:图形化工具连接配置
命令行是基本功,但日常操作配合图形化工具效率高很多。Navicat、DBeaver、MySQL Workbench各有拥趸。Navicat是商业软件,界面友好功能强大;DBeaver免费开源,跨平台,连接MySQL、PostgreSQL、SQL Server都很方便;Workbench是MySQL官方产品,免费,但很多用户反馈使用体验一般。
用Navicat连接本机MySQL,需要注意几个关键配置:主机填localhost或127.0.0.1,端口填3306(如果改过端口就填你改的),用户名root,密码是你登录用的密码。
连接报Can't connect to MySQL server on localhost (10061)的话,排查思路通常是:MySQL服务没启动;端口不是3306(可能你自己改过);或者MySQL当前绑定了别的IP。快速定位方法:命令行执行netstat -ano | findstr 3306,看端口有没有监听。没监听就是服务没起来,有监听就是连接参数不对。
6. 新手高频报错全整理:含排查思路和避坑技巧
6.1 经典报错一:ERROR 1045 (28000): Access denied for user
看到这个错误,意思就是用户名或密码不对,或者这个用户没有权限从当前主机登录。按下面顺序排查:
- 确认输入的用户名和密码没有输错(注意,MySQL密码是区分大小写的)
- 确认用户登录的host限制,如果
'root'@'localhost'只允许本机登录,你用远程IP连就会被拒 - 密码实在想不起来,按上文方式重置
6.2 经典报错二:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock'
这个报错在Linux/macOS下特别常见,核心就是MySQL服务没启动,或者客户端连接时找不到socket文件。可以先确认服务状态:在Linux上用systemctl status mysqld或者service mysql status,服务没启动就systemctl start mysqld。如果启动了还是报这个,很可能是socket文件路径不对,可以手动指定:
bash复制mysql -u root -p -h 127.0.0.1 -P 3306
指定TCP连接,绕开socket文件,能连上就说明服务本身没问题。
6.3 经典报错三:ERROR 1064 (42000): You have an error in your SQL syntax
SQL语法错误。MySQL很贴心地会在提示信息里用箭头标出出错位置附近的内容。常见原因有:关键字拼错了、字符串忘加引号(单引号)、语句没结束(忘了分号)、中文标点混进了SQL。新手最难以排查的是中文标点问题,看起来一样,但MySQL识别不出来。
判断技巧:把整条SQL复制出来在文本编辑器里看,仔细检查引号、括号、逗号是不是英文半角符号。
6.4 经典报错四:Incorrect string value: '\xF0\x9F\x98\x80'
这是往utf8字符集的表里插入emoji表情时报的错。原因就是前面讲的utf8只支持3字节,而emoji需要4字节。解决办法:表、字段、连接三层的字符集都要改成utf8mb4。改字段的SQL是:
sql复制ALTER TABLE student CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
连接字符串或配置文件里的character-set-server=utf8mb4也要确认。
6.5 经典报错五:Port 3306 is already in use
装MySQL的时候提示端口被占用,通常是机器上装了旧版本MySQL、或者MariaDB、或者别的软件占用了3306。解决办法有两个:把占用的软件卸载/停止;或者换一个端口。改端口需要改配置文件my.ini里的port=3307,然后重启服务。如果只是临时测试,改端口更省事,但后面所有客户端连接和代码里的连接地址都要同步改,容易遗漏。
结合我这么多年帮别人排查问题的体验,很多报错根本原因是“环境差异”而不是SQL写错。同一段代码,在自己电脑上好的,换台机器就报错,优先对比MySQL版本、字符集、sql_mode配置,这三个因素占了环境差异的大头。
SQL这门手艺,理论看十遍不如动手跑一遍。照着这篇文章的步骤,把student表建起来,插入几条数据,再试几个查询、修改和删除,你就算真正入了MySQL的门。后面再碰到不懂的,多去看官方文档,多拿真实数据集练手,慢慢就能从“会操作”进化到“会设计”,这条路我走过,确实不难。
