2026/10/3 3:36:00

MySQL新手入门指南:从环境搭建到SQL增删改查与避坑实践

MySQL新手入门指南:从环境搭建到SQL增删改查与避坑实践 购买整理过的内容。我将谨慎、精炼地组织点。现在输出最终博文。1. 项目概述为什么我建议从MySQL和SQL入门前几天有个刚转行做数据分析的朋友问我想学数据库到底从哪儿下手我给他的回答一直很直接——先装一个MySQL然后踏踏实实把SQL基础语句练熟。别一上来就研究什么分布式数据库、列式存储、窗口函数对新手来说SQL是打开数据世界的那把钥匙MySQL则是练手最舒服的训练场。这个系列的第一篇我就把「环境搭建 第一天该学会的SQL语法 新手最爱踩的坑」一次讲清楚。MySQL是当前应用最广的开源关系型数据库之一很多互联网公司的业务数据都躺在它上面SQL则是和数据库打交道的通用语言学会了它不管以后换PostgreSQL、SQL Server还是云上的数据库产品核心思路基本都是通的。这篇文章不想把SQL讲成教科书我会按自己这些年实际干活的经验来从零开始带你把这套东西跑通。这篇博文适合谁刚入门后端、想转数据岗位的菜鸟以及在学校学过理论但没动手建过表的同学。我会把安装、建表、增删改查、去重、排序、分组、连接挨个过一遍再分享几个真实的翻车案例比如忘记加WHERE导致全表数据被改、密码过期连不上数据库、连接时报SSL错误这类问题。第一篇的内容以打地基为主不追求高深但保证你跟着做完脑子里能真正建立起SQL的完整轮廓。2. 开干之前MySQL环境搭建是第一个敲门砖2.1 版本选择是很多人忽略的坑我见过太多新手卡在安装这一步一搜教程发现五花八门有5.7的、8.0的、还有8.4的直接懵了。这里给你的建议是如果你没有历史项目包袱直接用MySQL 8.0系列。8.0默认存储引擎是InnoDB支持窗口函数、公用表表达式这些现代SQL特性而且安装包和学习资料最多。5.7虽然经典但已经处于生命周期末尾新手没必要从老版本开始。下载时一定去官网别在第三方站随便下。选MySQL Community Server这是免费社区版功能和商业版在基础使用上没有区别。Windows用户下载.msi安装包Linux用户根据发行版选.tar.gz或用系统包管理器安装。安装过程中需要注意几个设置项端口号保持默认的3306即可除非你本机已经占用认证方式8.0默认使用caching_sha2_password本地学习直接用默认就好root密码务必记牢后面所有操作都靠它。2.2 启动服务和首次连接安装完并不是马上就能用你得先确保MySQL服务启动了。Windows下可以按WinR输入services.msc打开服务管理器找到名为MySQL80的服务右键启动Linux下用systemctl start mysqld。启动之后在命令行输入下面这段会提示你输入密码mysql -u root -p输入正确密码后你会看到mysql提示符到了这一步环境就算通了。我先建议你执行一句简单的SQL验证一下SELECT VERSION();能返回类似8.0.xx的版本号说明你的MySQL完全正常可以开始干活了。提示在MySQL命令行里每条SQL语句结尾都要加英文分号不然回车后它会以为你还有下一行要写。2.3 用图形工具还是命令行学习阶段我强烈建议你两条腿走路命令行必须认识图形工具也要会用。命令行能让你深刻理解每条语句的执行逻辑但图形工具能让你更快看到表和数据的全貌。MySQL官方自带的MySQL Workbench是个不错的选择免费、跨平台、功能全。连接时填主机名127.0.0.1、端口3306、用户名root和密码点Test Connection测试通过后保存即可。我用过的工具里轻量的话可以用DBeaver也很顺手。不过第一篇我不建议你在工具上花太多精力命令行窗口开起来老老实实敲几遍语句比什么工具都管用。3. 第一天SQL建库建表和增删改查3.1 先搞清楚数据库和数据表是什么关系拿我们日常的文件柜来类比数据库就是一个大文件柜数据表是柜子里的文件夹每条记录是文件夹里的一张纸。一个MySQL服务实例可以创建多个数据库一个数据库里可以有多张表。新手最容易犯的错误是还没想清楚就直接建表结果表里应该放哪些字段全凭拍脑袋后期改起来非常痛苦。所以规范的流程是先创建数据库再切换到对应的数据库然后创建表最后才往里灌数据。每一步都得想清楚这个表要存的核心业务是什么。3.2 建库建表实操我用一个最贴近业务场景的例子维护一个用户信息表。第一步创建数据库CREATE DATABASE user_manager CHARACTER SET utf8mb4; USE user_manager;注意我加了utf8mb4字符集。新手经常会忽略这个如果你要存中文、表情符号不用utf8mb4很容易出现乱码。第二步创建用户表CREATE TABLE app_user ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, age TINYINT, score DECIMAL(5,2), created_at DATETIME DEFAULT CURRENT_TIMESTAMP );这里面的字段类型我用几个通俗的说法解释INT AUTO_INCREMENT PRIMARY KEY整数自增主键。这条数据进来后会自动编号从1开始往后加不需要你手动指定VARCHAR(50)最长50个字符的可变长度字符串适合用户名、邮箱这类内容TINYINT小整数存年龄绰绰有余DECIMAL(5,2)精确小数总共5位数字小数点后占2位存成绩、金额必备。不要用FLOAT存金额类数据会有精度问题这是我最想提醒你的一条DATETIME DEFAULT CURRENT_TIMESTAMP插入数据时自动填上当前时间。3.3 插入数据INSERT表建好了往里加数据用INSERT。先来一条最简单的INSERT INTO app_user (username, age, score) VALUES (阿明, 23, 88.50);因为我们设置了主键自增所以id这一列可以不写。多行数据一次插入用逗号分隔INSERT INTO app_user (username, age, score) VALUES (小红, 24, 92.00), (小王, 22, 85.50), (小张, 23, NULL);这里开始你就会遇到第一个常见坑字符串必须用单引号包起来数字不用。NULL是真正什么都没有别用空字符串去代替没有值这个语义。3.4 查询数据SELECT和WHERESELECT是SQL里使用频率最高的语句没有之一。查询全部数据SELECT * FROM app_user;*代表所有列日常调试很方便但项目上线后我不建议写*因为不需要的字段查出来纯属浪费资源后面我会再讲。带条件查询是常态SELECT username, score FROM app_user WHERE score 80;WHERE后面跟条件表达式支持、、、、、!这些比较符。多个条件可以用AND、OR组合SELECT username, score FROM app_user WHERE age 22 AND score IS NOT NULL;这里特别提醒判断某列是否为NULL必须用IS NULL或者IS NOT NULL写score NULL是永远不成立的这在SQL里是个经典大坑我先给你打过预防针了。3.5 修改数据UPDATEUPDATE用于修改已有数据基本的格式是UPDATE app_user SET score 90.00 WHERE username 小王;这句话的含义是把用户名为小王的这条记录的分数改成90分。问题出在WHERE条件如果漏写了就会变成UPDATE app_user SET score 90.00;所有用户的分数都会被修改成90。我可以说每个用MySQL的人几乎都经历过这种事故要么是忘了WHERE要么是WHERE条件写得太宽。改数据之前先想一想这条语句到底想影响哪几行先写一条SELECT看效果再改成UPDATE执行这个习惯能保命。3.6 删除数据DELETE和DROPDELETE删除表里的数据DROP直接删掉整张表两者的杀伤力完全不同。删除指定数据DELETE FROM app_user WHERE id 4;同样是WHERE的教训不带条件的DELETE FROM app_user;会把表清空连后悔药都没有。如果你确实想清空一张表可以用TRUNCATE TABLE app_user;它比DELETE更快但它连自增计数也会重置而且部分操作无法回滚。使用前一定确认自己是不是真想这么做。至于DROP TABLE app_user;执行完表就没了数据文件也一起删除这条命令上手之前请深呼吸三秒。4. 把SQL用得更溜去重、排序、分组和连接4.1 去重DISTINCT的使用场景与隐患热门搜索里DISTINCT相关的问题特别多因为去重几乎是任何业务都会遇到的需求。比如你想知道用户表里一共有多少个不同的年龄SELECT DISTINCT age FROM app_user;这条语句会把所有年龄值去重后列出来。如果你想统计去重后的数量配合COUNT使用SELECT COUNT(DISTINCT age) FROM app_user;去重看起来简单但有几个细节容易被忽略。第一DISTINCT作用在它后面所有列的组合上SELECT DISTINCT age, username是对年龄和用户名同时去重不是单独对年龄去重。第二DISTINCT会在排序时额外消耗资源数据量大的表上不要滥用。第三NULL值在去重时会被保留为一个分组所以结果里可能出现一行NULL别奇怪。4.2 排序ORDER BY的排序规则展示数据时最常用到的就是排序比如按分数从高到低排SELECT username, score FROM app_user ORDER BY score DESC;DESC表示降序ASC表示升序不写默认是升序。多字段排序也不难举个例子先按年龄从小到大同年龄的人再按分数从高到低SELECT username, age, score FROM app_user ORDER BY age ASC, score DESC;ORDER BY的执行顺序其实是在WHERE过滤之后进行的所以你可以放心把过滤和排序放在同一条语句里SELECT username, age FROM app_user WHERE age 20 ORDER BY age;排序时还有一个新手容易疑惑的点字符串字段排序是按字母或者字符编码顺序排的不是按拼音。中文按字母排序其实会按字符集编码来排想按拼音规则排序需要用ORDER BY CONVERT(username USING gbk)这种方式不过这一篇你先知道有这回事就行不用死记。4.3 分组聚合GROUP BY和HAVING分组是SQL比Excel透视图更强大的一点。比如我想统计每个年龄段的用户人数SELECT age, COUNT(*) FROM app_user GROUP BY age;这里COUNT(*)统计的是每组有多少行。常用的聚合函数还有SUM、AVG、MAX、MIN。分组之后如果还想对聚合结果做筛选不能再用WHERE要用HAVING。比如找出平均成绩大于85分的年龄组SELECT age, AVG(score) AS avg_score FROM app_user GROUP BY age HAVING AVG(score) 85;WHERE是在分组之前过滤原始数据HAVING是在分组之后过滤聚合结果这两者的区别是面试题里的常客你趁早分清楚。4.4 表连接JOIN其实没那么难很多新手一看到JOIN就害怕但它的本质就是把两张表按某个关联字段拼在一起。我用更贴近现实的例子再建一张订单表记录每个用户买了什么。CREATE TABLE app_order ( id INT AUTO_INCREMENT PRIMARY KEY, user_id INT, product_name VARCHAR(100), amount DECIMAL(10,2) );现在想查每个订单对应的用户姓名就可以把用户表和订单表拼起来SELECT app_order.product_name, app_user.username FROM app_order INNER JOIN app_user ON app_order.user_id app_user.id;INNER JOIN是内连接只返回两表能匹配上的数据。如果某条订单对应用户已经删了这条订单在结果里就不会出现。想保留订单这边所有数据可以用LEFT JOIN它会把左表FROM后面的表所有数据都保留右表没有匹配的就显示NULL。建议你亲自建两张简单的表试几遍连接并不可怕配合图表和实际输出结果很快就能理解。4.5 性能意识索引和慢查询初认识新手阶段就该建立一点性能概念免得一上了生产环境就翻车。数据量小的时候一条查询怎么写成无所谓等表里有上百万行数据缺索引的查询会慢到怀疑人生。索引的本质就是书的目录它让MySQL不需要逐行扫描整张表就能快速找到数据。拿上面的例子来说如果你经常按username查用户就可以加一个索引CREATE INDEX idx_username ON app_user(username);判断一条查询到底有没有用到索引在语句前面加EXPLAIN比如EXPLAIN SELECT * FROM app_user WHERE username 阿明;返回结果里type这一列如果是ALL说明是全表扫描查询量大时肯定慢如果看到index或者ref等说明走索引了。慢SQL优化是个大话题但第一条经验就是好索引的最直接效果就是消除全表扫描。另外我在实际开发中也很少用SELECT *需要什么字段就查什么字段这既是为了减少数据传输也更容易让优化器做出正确的执行计划。5. 新手最容易翻车的几个雷坑5.1 语法层面的经典翻车新手写SQL报错很大概率出在引号、逗号、关键字这三件事上。字符串和日期条件一定要用单引号双引号在MySQL里默认是字符串的一个部分别混用VALUES后面多行数据之间用逗号每行括号内部的字段个数必须和前面的列名数量一致不一致直接报Column count doesnt match value count。还有个很坑的是字段名撞上保留字比如我有张表里有人用desc、order当字段名查的时候报语法错解决办法是用反引号把它括起来SELECT desc FROM app_user;5.2 忘写WHERE导致的事故现场我亲眼见过同事执行DELETE FROM order_info;的时候以为自己加好了条件其实整张订单表瞬间被清空。这种事故绝不罕见。我自己现在养成了几个习惯分享给你更新和删除之前先把同样的WHERE条件拿到SELECT里面跑一遍看看会命中多少行重要表的重要更新操作最好先开启事务见下面的第6章不打算影响全表时SQL里刻意写一个永远不会为真的条件比如WHERE 1 2用来防止手滑。5.3 NULL和空字符串不是一回事这是我在答疑时反复要解释的点。NULL表示没有值表示有一个空字符串。比如用户备注字段一个人没填备注是NULL填了内容后清空变成了空字符串这两个状态在统计时截然不同。查询时column 能查到空字符串的记录但查不到NULL反过来用column IS NULL也查不到空字符串。很多统计数字对不上就是这种边界条件没考虑清楚。5.4 连接数据库报错的排查思路在热门搜索里看到一堆mysql连不上SSL连接错误Access denied这类词我从生产环境的角度帮你梳理一下最常见的几种报错报错现象大概率原因排查方向Cant connect to MySQL server服务没启动或端口不通检查服务状态、3306端口是否开放、云服务器安全组是否允许Access denied for user rootlocalhost密码错误或账号权限问题检查密码确认用户该从哪个host登录Authentication plugin caching_sha2_password访问方客户端太老不认识新认证插件升级客户端驱动或改用专用连接参数SSL connection errorSSL握手失败或证书不匹配检查连接串是否强制SSL必要时指定ssl-mode重试SSL连接错误这个坑值得多说两句。MySQL 8.0默认会使用SSL加密连接有时候客户端或者JDBC驱动的SSL参数配置不对就会在握手阶段直接失败。实际经验是先把本机加密的CERTIFICATE验证方式检查一遍如果只是为了本地开发调试可以改用信任所有证书的模式但生产环境必须保留合法的证书校验安全永远优先这点不要省。5.5 忘记密码怎么办忘了root密码是很多人会经历的事。操作思路大致是先停掉MySQL服务再以跳过权限验证的方式启动修改密码最后恢复正常启动。Linux下大概是这几步systemctl stop mysqld mysqld --skip-grant-tables mysql -u root进入MySQL之后执行ALTER USER rootlocalhost IDENTIFIED BY 新密码; FLUSH PRIVILEGES;改完之后重启服务用新密码登录。这个方法可以应急但--skip-grant-tables模式下数据库没有任何鉴权保护只能在内网、短时间、确保无外人访问的情况下用用完马上恢复正常模式。生产环境里的密码策略通常会更严格密码过期是另一类常见问题登录后提示密码过期时执行ALTER USER重新设置密码即可。5.6 从第一天就防SQL注入搜索词里SQL注入出现的频率很高这是Web安全里最经典也最致命的漏洞之一。它的原理不难理解如果在代码里把用户输入的内容直接拼接到SQL语句中攻击者就可以通过输入特殊字符改变SQL的语义。一个经典的拼接写法比如Java里String sql SELECT * FROM app_user WHERE username input ;如果用户输入的input是 OR 11拼接出来的SQL就会变成SELECT * FROM app_user WHERE username OR 11;条件永远为真等于把全部用户数据都查出来了。更严重的版本还能拼接出DELETE、DROP语句直接把表删了。正确做法是所有动态SQL都要用参数化查询或者预编译语句把用户输入当成参数而不是可执行代码的一部分。这个意识越早建立越好不要等上线被扫描出漏洞再补课。6. 延伸概念事务为什么值得你提前认识6.1 用转账场景理解ACID事务这个概念听起来很高大上但用生活例子讲就很直白A给B转账100块在数据库里分两步先从A账户扣100再给B账户加100。如果第二步失败了呢总不能只扣钱不加钱吧。事务就是保证这两步要么全部成功要么全部回滚的一条安全绳。事务有四个特性缩写叫ACID新手不用死记英文你只要抓住关键原子性操作要么全成、要么全废、一致性数据前后不能矛盾、隔离性多个事务并发时互不干扰、持久性提交后不会丢。这四个特性是关系型数据库能成为企业核心存储的根本原因。6.2 事务实操BEGIN、COMMIT、ROLLBACK在MySQL里InnoDB引擎默认每一条语句都是自动提交的所以你不需要手动开事务也能执行INSERT。但遇到多条关联操作时你必须手动控制START TRANSACTION; UPDATE account SET balance balance - 100 WHERE user_id 1; UPDATE account SET balance balance 100 WHERE user_id 2; COMMIT;执行到一半发现数据不对可以改成ROLLBACK;这样两条UPDATE会一起撤掉。我在日常开发里对删除用户并清空其订单批量修改核心字段这类动作十次有九次都先开事务确认无误再COMMIT。提交之后数据改动就生效了再想后悔只能靠备份恢复那代价就大了。6.3 第一篇之后的学习路线到这里第一篇的核心任务就完成了。你已经能安装MySQL、建库建表、完成增删改查还知道去重、排序、分组、连接的基本写法顺便避开了不少新手坑。下一阶段我建议按这个顺序往下走先练熟JOIN和聚合再啃索引和EXPLAIN然后学视图、存储过程和触发器最后学备份恢复和主从复制。存储过程、事务隔离级别这些内容是后面几篇的重头戏第一篇不用急着啃。我的经验是基础SQL语句每天敲半个小时敲一周比看一周教程都有效数据库这门手艺动手永远是最快的。最后再分享一个我一直在用的习惯学习时给自己建一个练习库随便造点熟悉的业务数据比如借书管理系统超市库存表然后每天给自己出几个查询题目答不上来就翻笔记。等你能不看任何资料写出一张表的完整增删改查SQL的入门关就算真正过了。