ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

MySQL零基础到实战:安装配置、SQL基础与调优进阶指南

MySQL零基础到实战:安装配置、SQL基础与调优进阶指南 1. 先把版本和安装方案定下来再动手装不迟我在电脑前折腾 MySQL 的次数多到自己都记不清了。从最初在官网里找不到下载入口到后来能一口气把环境变量、基础代码、常见报错讲清楚中间踩过的坑几乎可以写成一本书。很多新手一上来就搜MySQL 安装教程复制一段命令就往终端里粘贴结果装到一半发现版本不对、服务起不来、命令行敲 mysql 直接报不是内部或外部命令然后整个人就懵了。这篇文章我打算从零开始把下载安装、配置环境变量、基础代码一次讲完同时把大家在搜索时经常遇到的存储过程排序update 语法字符串转日期索引连接池主从复制这些词串到对应的章节里去。适合完全没接触过数据库的人也适合已经装了 MySQL 但没理清概念的初学者。1.1 去官网下载哪个版本打开搜索引擎搜mysql 下载官网前几条通常都是 mysql.com 的官方页面。认准 MySQL Community Server 这个免费社区版就够了企业版功能更多但学习阶段完全用不上。版本号怎么选现在主流是 8.0也就是 MySQL 8.x 系列。如果你只是自己学、自己练习直接下最新的 8.0 稳定版如果你进公司接手老项目项目文档里大概率写的是 5.7。5.7 和 8.0 在大部分基础语法上差别不大但 8.0 在认证方式、字符集默认值、窗口函数等方面都有变化。所以我给新手的建议是新项目、自学、写demo选 8.0要维护老系统先问问同事项目的 MySQL 版本再决定装哪个。还有一个经常被问的Windows 上到底下载 MSI 安装包还是 ZIP 压缩包MSI 是图形化安装向导跟着点下一步就行适合新手。ZIP 是免安装版本解压后手动初始化数据目录、注册服务适合喜欢掌控每一步的人。两种都能用但第一次装 MySQL 的人我推荐 MSI。1.2 Windows、Linux、Docker 三种安装思路对比不同场景下安装方式差别很大。我整理了一个对照表场景推荐方式理由本地开发WindowsMSI 安装包图形化界面服务自动注册适合新手本地开发macOSHomebrew 直接装命令少卸载也干净服务器部署Linux官方 rpm / apt 源和系统服务集成好方便用 systemctl 管理临时测试 / 项目隔离Docker 容器起一个实例只要几分钟不污染宿主机很多人问linux 离线安装 mysql怎么搞其实就是下载 Linux 通用版的 tar 包或者对应发行版的 rpm 包传到服务器上手动解压安装。离线环境没有 yum 源需要自己处理依赖适合对 Linux 有一定基础的人。我个人建议如果服务器能联网永远先试官方源实在离线再考虑 tar 包方式。Docker 方式也值得提一句。现在很多后端项目用 Docker 部署 MySQL好处是版本隔离、删了重建都很快。比如你手上同时有 5.7 和 8.0 的老项目Docker 里各跑一个实例互不干扰这在本地开发和测试阶段特别爽。2. Windows 上用安装包装 MySQL手把手步骤和两个容易卡住的点Windows 下安装 MySQL 8.0过程并不复杂但有两个地方新手特别容易卡住一个是 root 密码策略一个是装完以后服务没启动。下面我把流程完整走一遍。2.1 安装向导里每一步都在做什么从官网下载 MSI 文件后双击运行安装类型通常建议选 Server only因为 MySQL Installer 自带了很多周边组件比如 MySQL Workbench、MySQL Shell新手用不到的时候可以先不装避免界面太乱。到了 Select Products 这一步你可以勾选 MySQL Server 8.0.x旁边如果有 MySQL Workbench建议一起勾上后面写 SQL 时用图形界面查看结果会更直观。之后是 Installation 页面点 Execute 开始下载安装。比较关键的一步是 Type and Networking。默认端口 3306一般不用改。如果你的机器上已经装了老版本 MySQL或者别的服务占用了 3306可以改成 3307但要记清楚后面连接时也要写对应端口。接下来设置 Authentication MethodMySQL 8.0 默认推荐 Use Strong Password Encryption这个保持默认就行。然后设置 root 密码。这里我多说一句不要设太简单的密码。密码策略那一步如果选了强密码校验你设个 123456 它会直接不通过这不是安装程序有问题是安全策略在起作用。建议设成包含大小写字母和数字的密码比如 Mysql2024 这种并且把它记在本子上因为这个密码后面每分钟都会用到。Windows Service 配置页面保持默认勾选 Configure MySQL Server as a Windows Service服务名默认 MySQL80开机自动启动也勾上。到这里一路 Next最后 Apply 执行完安装就结束了。2.2 装完先别急着写代码先跑通 mysql -u root -p打开命令行工具cmd 或 PowerShell输入mysql -u root -p回车后会提示输入密码输入刚才设置的 root 密码看到mysql提示符就说明装好了。你可以先敲一句最简单的命令验证SELECT VERSION();正常会输出类似8.0.36的版本号。如果你在这一步遇到mysql 不是内部或外部命令的提示别慌这不是 MySQL 没装好而是系统还不知道去哪找 mysql.exe这就是环境变量的问题。我放在下一章专门讲。另一类常见问题输入mysql -u root -p之后提示连接不上比如ERROR 2003 (HY000): Cant connect to MySQL server on localhost:3306。这通常是 MySQL 服务没启动。打开服务管理面板Win R 输入 services.msc找到 MySQL80右键启动。2.3 如果服务没启动MySQL 安装完之后服务默认是自动启动的但偶尔也会出现启动失败的情况。这时候不要急着重装先看两个地方服务状态是不是正在运行。如果显示已停止点启动按钮看会不会报错。Windows 事件查看器里找 MySQL 相关的错误日志路径一般和 MySQL 安装目录下的 data 文件夹有关。一个很常见的原因是安装目录权限不足。确保 MySQL 安装目录和数据目录的读写权限正常尤其是自定义安装路径到 C:\Program Files 之外或者 D 盘时Windows 对权限比较敏感。把服务启动方式改成自动然后重新启动计算机再试试大多数问题都能解决。3. 配置环境变量理解了 PATH 的逻辑就不怕配错环境变量这个问题很多装了 MySQL 用不了命令行的人最终都会遇到。其实理解一个点就够了当你在命令行里输入 mysql操作系统是在一堆默认目录里寻找 mysql.exe 这个文件找不到就报错。配置环境变量本质上是告诉系统你还可以去哪个目录找我。3.1 Windows 里配置 PATH 的完整路径首先找到 MySQL 的安装目录。如果你用的是 MSI 默认安装路径一般是C:\Program Files\MySQL\MySQL Server 8.0\bin注意bin子目录里才是 mysql.exe 和 mysqldump.exe 等可执行文件。然后右键此电脑 - 属性 - 高级系统设置 - 环境变量在系统变量里找到 Path双击编辑点击新建把上面的 bin 目录地址粘贴进去确定保存。完成后重新打开一个命令行窗口注意是重新打开旧窗口不会刷新环境变量再输入mysql -u root -p就能正常连接了。很多人配置完仍然提示找不到命令十有八九是没开新窗口。这里有个忠告只添加你自己 MySQL 的 bin 目录不要动系统已有的其他 Path 条目更不要把 Path 整个替换掉。一旦改坏可能连系统基础命令都会受影响。3.2 Linux 下的环境变量配置Linux 上如果你是通过 apt 或 yum 安装的 MySQL通常不需要手动配命令已经在 PATH 里。但如果用 tar 包解压安装到/usr/local/mysql就需要自己配export PATH$PATH:/usr/local/mysql/bin这种写法是在当前 shell 临时生效关掉终端就失效了。要永久生效把它写进 shell 配置文件。以 bash 为例echo export PATH$PATH:/usr/local/mysql/bin ~/.bashrc source ~/.bashrcsource命令是让配置立即生效很多初学者忘了这一步以为配置没写对。4. 基础代码从建库建表到增删改查一行一行讲明白装好 MySQL 之后重点就是写代码了。你会发现数据库的基础操作并不难核心就是增删改查但每一句语法都有必须遵守的规则。下面我以一个小项目常用的用户表为例把基础代码完整过一遍。4.1 建库建表先想清楚字段再动手写进入 MySQL 命令行后先建一个数据库CREATE DATABASE IF NOT EXISTS demo DEFAULT CHARACTER SET utf8mb4; USE demo;字符集我用 utf8mb4因为 MySQL 8.0 默认就是它能存 emoji 和中文不会出现乱码。然后建表CREATE TABLE user ( id INT NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL, age INT DEFAULT 0, create_time DATETIME NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;这个表里有几个基础知识点AUTO_INCREMENT表示自增每次插入数据时不用手动填 id数据库会自动加 1VARCHAR(50)表示可变长度字符串最长 50 个字符DEFAULT 0就是热搜里常看到的mysql 设置默认值为 0意思是这条字段如果不传值就默认填 0。4.2 插入数据两种写法都要会单条插入INSERT INTO user (name, age, create_time) VALUES (张三, 18, NOW());多条插入逗号分隔INSERT INTO user (name, age, create_time) VALUES (李四, 20, NOW()), (王五, 22, NOW()), (赵六, 25, NOW());NOW()是取当前时间适合 create_time 这种字段。注意我写插入时没有给 id 赋值因为它是自增主键数据库会自动处理。4.3 UPDATE 的坑忘记 WHERE 条件会全表更新mysql update 语法本身很简单UPDATE user SET age 19 WHERE name 张三;但我见过太多新手包括我自己刚学的时候写过这种代码UPDATE user SET age 19;这条语句没有一个 WHERE 条件意思就是把表里所有记录的 age 都改成 19。更危险的是如果是在生产环境执行数据就直接被批量覆盖了。这个教训是真金白银换来的写 UPDATE 和 DELETE 语句时先看一眼 WHERE 条件再执行永远要把不带条件的更新删除当成事故来防。如果想更新多个字段用逗号分隔UPDATE user SET age 20, name 张三丰 WHERE id 1;4.4 SELECT 查询、排序和条件过滤最基础的查询SELECT * FROM user;*表示所有列。生产环境建议把字段名列出来写SELECT id, name, age FROM user;这样表结构变动时影响小数据传输量也小。条件查询用 WHERE 和 AND / ORSELECT id, name, age FROM user WHERE age 20 AND age 30;排序用 ORDER BY。mysql 排序有两种方向ASC升序默认DESC降序SELECT id, name, age FROM user ORDER BY age DESC;多字段排序比如年龄相同再按 id 从小到大SELECT id, name, age FROM user ORDER BY age DESC, id ASC;分页查询用 LIMITSELECT id, name, age FROM user ORDER BY id LIMIT 10 OFFSET 20;这个语句的意思是跳过前面 20 条取 10 条。OFFSET 是偏移量底层逻辑是从第 0 条开始数所以第一页是LIMIT 10 OFFSET 0第二页是LIMIT 10 OFFSET 10。这个细节经常在面试中问到。删除数据DELETE FROM user WHERE id 1;同样WHERE 条件是必须的否则就是清空全表。5. 字符串转日期、默认值为 0、索引和锁这些基础但不简单的知识点基础增删改查只是开始。实际项目中你会经常遇到类型转换、默认值、查询性能这些绕不开的问题。这一节我把几个高频知识点一次性讲清楚。5.1 字符串和日期怎么互转接口传参、Excel 导入、日志解析这些场景里日期经常是字符串形式。MySQL 提供了很直接的函数。字符串转日期SELECT STR_TO_DATE(2024-08-15 10:30:00, %Y-%m-%d %H:%i:%s);%Y是四位数年份%m是月份%d是日期%H是 24 小时制的小时%i是分钟%s是秒。格式串里的分隔符要和原字符串保持一致。日期转字符串用 DATE_FORMATSELECT DATE_FORMAT(NOW(), %Y-%m-%d);输出结果是2024-08-15这一步在做报表、导出文件时非常常见。还有一个很实用的函数 CAST可以做基础类型转换SELECT CAST(123 AS SIGNED);这种转换要小心CAST(123abc AS SIGNED)在 MySQL 中会返回 123并不会直接报错但在某些严格的数据库里会直接报异常所以程序里做转换时还是建议先做数据校验。5.2 DEFAULT 0 到底怎么设置设置默认值为 0在 CREATE TABLE 时已经写过CREATE TABLE order ( id INT NOT NULL AUTO_INCREMENT, status TINYINT NOT NULL DEFAULT 0, PRIMARY KEY (id) );status字段不填时就是 0比如订单刚创建状态就是待处理。如果你表已经建好了想修改字段默认值用 ALTER TABLEALTER TABLE order MODIFY COLUMN status TINYINT NOT NULL DEFAULT 0;这里注意MODIFY 是整列修改要完整地写一遍字段类型和约束不要只写 DEFAULT。5.3 索引为什么能提速为什么不能乱加每次查询都在全表扫描数据少的时候没感觉数据到了百万级别一条不带索引的查询可能慢到你怀疑人生。mysql 创建索引的语法CREATE INDEX idx_user_age ON user (age);比如有这样一个查询SELECT * FROM user WHERE age 22;执行这条语句时MySQL 会优先走索引快速定位到年龄是 22 的记录而不是一行一行扫描整张表。但索引不是越多越好。每建一个索引写入数据时都要额外维护索引结构相当于图书后面又多了一本目录要同步更新。写多读少的表索引要克制。还要注意索引本身要遵循最左前缀原则联合索引里第一个字段没有出现在 WHERE 条件里时索引可能不会生效这个面试里也常考。5.4 表锁与锁表排查的日常MySQL 的锁知识很深但新手至少要知道一个事务改了某行数据在提交之前会锁住该行InnoDB 引擎默认行锁如果修改的是整表结构或者加了表锁其他操作就会被堵住。实际开发中偶尔会遇到某个更新卡了很久十有八九是有别的连接把行锁住了事务一直没提交。排查思路是这样的。用 root 身份登录执行SHOW FULL PROCESSLIST;找到状态为Waiting for table metadata lock或Lock wait timeout exceeded的连接用 KILL 杀掉KILL 12345;其中 12345 是 processlist 里的 Id 字段。这个技能在项目上线维护时非常实用我建议至少要把这条 SQL 记在本地笔记里。6. 存储过程与触发器把重复 SQL 封装起来的高级基础热搜里有mysql 存储过程mysql 声明存储过程mysql 中触发器中分隔符说明很多人学到这里开始进入另一个阶段把多条 SQL 打包起来像函数一样调用。这部分不算特别难但对基础语法的理解要求更高。6.1 DELIMITER 到底是怎么回事在命令行里写存储过程和触发器你会看到一段奇怪的语法DELIMITER // CREATE PROCEDURE ... END // DELIMITER ;这是因为 MySQL 默认使用分号作为一条语句的结束标志。存储过程内部是有多条语句的每条都以分号结尾MySQL 遇到第一个分号就会认为 SQL 结束然后报错。DELIMITER //就是把语句结束符临时改成//让 MySQL 知道整段存储过程只有遇到//才算结束。写完以后要重新DELIMITER ;改回来。6.2 一个最简单的存储过程实例需求统计 user 表里的总人数。DELIMITER // CREATE PROCEDURE count_users() BEGIN SELECT COUNT(*) AS total FROM user; END // DELIMITER ;创建后调用CALL count_users();如果想加参数比如按年龄下限统计DELIMITER // CREATE PROCEDURE count_users_by_age(IN min_age INT) BEGIN SELECT COUNT(*) AS total FROM user WHERE age min_age; END // DELIMITER ; CALL count_users_by_age(18);存储过程适合把业务逻辑沉淀在数据库里比如批量对账、月结跑批。但我个人的经验是能用程序代码实现的逻辑尽量写在应用层存储过程少用。原因很简单存储过程难调试、难版本管理一个不小心改错线上问题比普通代码更隐蔽。6.3 触发器注意分隔符和递归问题触发器的场景很典型用户下单时自动更新一张统计表。下面是一个简单触发器当 user 表插入数据时自动往 user_log 表里插入一条记录DELIMITER // CREATE TRIGGER trg_user_insert AFTER INSERT ON user FOR EACH ROW BEGIN INSERT INTO user_log(user_id, action, create_time) VALUES (NEW.id, insert, NOW()); END // DELIMITER ;这里的NEW代表新插入的记录可以用NEW.字段名拿到字段值。删除记录时触发器触发用的是OLD。触发器有个要小心的点它会在每次操作时自动执行如果你在触发器里又去修改同一张表很容易引发递归调用或者死锁。而且触发器上的 bug 难以追踪我建议能不用尽量不用。7. 装好后连不上ERROR 2002、SSL 报错、服务启动失败的排查手记很多人装完 MySQL 并不是立即使用而是先卡在连不上。这一节我把最常见的三个连接错误一次讲清楚后面你在搜索引擎里再看到它们就知道根源在哪了。7.1 ERROR 2002 的经典原因最常见的报错是这么写的ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock (2)这个问题在 Linux 和 macOS 上常见。报错的字面意思是无法通过/tmp/mysql.sock这个 socket 文件连接本地 MySQL。sock 文件是本地连接时 MySQL 创建的通信管道如果文件不存在或路径不对就会报错。排查步骤很简单检查 MySQL 服务是否在运行。Ubuntu 上执行systemctl status mysqlCentOS 上可能是systemctl status mysqld。如果服务没运行尝试启动systemctl start mysql。如果服务运行中仍然报错检查配置文件里 socket 路径。mysqld --verbose --help | grep socket可以看到默认 socket 路径如果和报错路径不一致改配置或者建软链接。大部分情况是第一步服务没起来。7.2 SSL 连接错误和 JDBC 参数现在用 Java 连接 MySQL 时常见报错是一些 SSL 相关的警告或直接失败。MySQL 8.0 默认开启 SSL连接时如果客户端和服务端没有正确协商证书就可能报错java.sql.SQLException: ... SSL connection error常见的解决办法是在 JDBC 连接串里加上 SSL 参数。比如jdbc:mysql://localhost:3306/demo?useSSLfalseserverTimezoneAsia/ShanghaiuseSSLfalse就是不使用加密连接。在开发环境、内外网隔离的情况下这么配没问题。如果公司强制要求加密连接那就得去配置服务器证书把useSSLtrue加上同时配置trustCertificateKeyStoreUrl和trustCertificateKeyStorePassword这些参数。Python 连接 MySQL 的库也有对应概念常见的是在连接参数里设置ssl_disabledTrue或者在 DSN 里写sslmodeDISABLED。总之记住一点SSL 报错多半是证书问题或者参数不一致先确认两端配置是否匹配。7.3 mysqld.service 起不来怎么办热搜里提到的mysqld.service - LSB: start and stop MySQL loaded这类问题本质是 Linux 上用 systemd 管理 MySQL 服务时启动失败。优先查日志journalctl -u mysqld -n 50大部分启动失败原因集中在三类数据目录权限不对。比如/var/lib/mysql的所有者不是 mysql 用户MySQL 没有权限读写。解决办法chown -R mysql:mysql /var/lib/mysql。数据目录初始化失败。如果是初始化过但没有成功删除旧数据目录重新初始化新手操作前一定要备份。端口被占用。改了配置里的端口或者杀掉占用 3306 的进程。排查顺序固定下来以后这类问题基本十分钟内能定位。8. 连接池、主从复制和性能调优面试里常问的那几题基础学会了以后很快会有人问mysql 的数据库连接池mysql 性能调优怎么使用 mysql 主从复制mysql 锁原理及面试题。这些内容单独每个都够写一长篇我这里把核心概念说清楚能帮助你把整体框架搭起来。8.1 连接池别把 MySQL 当永动机后端项目里程序每次操作数据库都要创建一个连接而创建连接的代价很高校验身份、分配资源等。连接池的作用是提前创建一批连接放在池子里程序需要时取一个来用用完还回去避免反复创建和销毁。常见连接池有 HikariCP、Druid 等。核心配置包括 minimum-idle、maximum-pool-size、connection-timeout。推荐连接池大小不是越大越好而是根据数据库实例规格来定。比如 4 核 8G 的 MySQL 实例连接池最大 20 到 50 就够了开太多连接只会让数据库忙于切换线程反而拖慢响应。8.2 主从复制一句话版本主从复制的核心思路是主库把每一个写操作记录到二进制日志binlog从库把主库的 binlog 拉到本地然后顺序执行让数据保持一致。这样读写可以分离主库负责写从库负责读降低单库压力。大致配置步骤是主库开启 binlog 并建一个复制账号从库连接主库读取 binlog 的位点然后启动复制进程。具体命令里常用的有CHANGE MASTER TO MASTER_HOST主库IP, MASTER_USER复制账号, MASTER_PASSWORD密码, MASTER_LOG_FILEmysql-bin.000001, MASTER_LOG_POS154; START SLAVE;面试里问到主从除了原理还经常问主从延迟问题。常见的延迟原因是主库写并发太高或者从库配置比主库差或者大事务在主库执行时间太长导致从库拉取日志落后。解决思路一般是优化大事务、选择合理从库配置、考虑并行复制。8.3 性能调优的第一批抓手mysql 性能调优是个大话题但新手不需要一开始就研究几百个参数。先把这三件事做好80% 的性能问题能缓解慢查询日志。日志打开每周看一眼执行时间超过 1 秒的 SQL针对其中出现最多的表加索引或者改查询逻辑。索引优化。用 EXPLAIN 分析执行计划EXPLAIN SELECT * FROM user WHERE age 22;看 key 字段是否为 NULL如果为 NULL 说明走了全表扫描需要加索引。避免SELECT *。查多少列就写多少列减少网络传输和内存占用。这里再补一个小知识很多人搜mysql 中 int5其实在 SQL 里写SELECT 1 5;会输出 6。MySQL 中的 INT 是整数类型整数和数字字面量做算术运算时引擎会把字符串转成数字处理。老项目里如果发现某些字段是字符串存数字这种运算偶尔会带来隐式转换性能损耗所以字段类型尽量一开始就用对。9. 我自己的日常小习惯以及给新手的最后几条忠告这些内容讲完后我再分享几个实际操作中的习惯算是对整篇文章的收尾。我每次装完 MySQL 都会做三件事一是把 root 密码写进本地的密码管理器而不是聊天记录二是确认服务开机自启三是连接到数据库执行一次SELECT VERSION();和SHOW DATABASES;确保命令行和图形界面都能正常访问。这三件事做完基础环境基本就稳了。接着我会用 Workbench 或 Navicat 这类图形客户端连一次。Navicat 连接 MySQL 时如果报 2059 错误通常是 MySQL 8.0 的密码认证方式问题需要在连接设置里调整插件为 caching_sha2_password或者把用户的认证插件改回 mysql_native_password。这个问题在 8.0 刚出来时非常常见现在很多客户端已经跟上来了。最后强烈建议养成备份的习惯。不用弄复杂脚本一条命令就够了mysqldump -u root -p demo demo_backup.sql恢复时执行mysql -u root -p demo demo_backup.sql我见过太多人在学习阶段把数据改乱了然后两眼一抹黑如果有备份恢复一下就是几秒钟的事。这些习惯我坚持了很长时间也算是在无数个低级错误中总结出来的保命技能。
返回列表