资讯动态

MySQL入门:从建库到增删改查的完整SQL实践与避坑指南

发布时间:2026/10/3 9:38:50 来源:尧图企业网站定制
2026年3月4日上午MySQL 学习笔记第 34 节创建数据库与运行各类 SQL。这句话如果放在以前我可能会觉得只是例行记录但今天把它当标题认真写下来其实是在提醒自己数据库入门阶段最容易忽略的恰恰是这些每天都要用的基础操作。很多人装完 MySQL 之后第一反应是赶紧去查“SELECT 怎么写”“JOIN 怎么连”结果连数据库都还没建出来。今天上午我给自己定的任务很简单也很扎实先创建一个 bookstore 数据库再建一张 books 表插入几条数据最后把增删改查完整跑一遍。这条路径走完SQL 的基本盘就稳了。1. 动笔之前先把 SQL 的类型理清楚1.1 SQL 四大分类每一类到底在管什么刚开始学 SQL 的人最容易犯的毛病是“见什么敲什么”完全不看这句话属于哪一类。实际开发中这条语句属于哪一类决定了你的操作范围、影响对象以及能不能回滚。DDLData Definition Language数据定义语言CREATE、ALTER、DROP、TRUNCATE。管的是表结构、数据库结构这类元数据执行后一般立即生效很多操作没法简单回滚。DMLData Manipulation Language数据操作语言INSERT、UPDATE、DELETE。管的是表里的数据是日常开发写最多的语句。DQLData Query Language数据查询语言SELECT。虽然也有资料把它归到 DML 里但单独拎出来更好理解它不改变数据。DCLData Control Language数据控制语言GRANT、REVOKE。管的是用户权限。至于COMMIT、ROLLBACK这类事务控制有的资料单独列为 TCL。我建议你在练习时先问自己一句这会改结构、改数据还是只是看数据答案不同对待方式也不同。改结构的语句要格外谨慎改数据的语句先确认 WHERE查数据的语句随便练出错最多浪费一点时间。1.2 学习路径为什么要按“库→表→数据→查询”走数据库里的一切操作都离不开一个前提你得先有库和表。没有库你的 SQL 不知道该往哪执行没有表数据就没有存放的容器。今天上午我安排的顺序是建库 → 建表 → 插数 → 查询 → 更新与删除。每一步都是下一步的基础。比如只有先建好表你才能谈插入数据时字段类型是否匹配只有插入了几行数据你才能验证查询条件到底写没写对。这种递进关系比单纯背语法要牢固得多。提示学习阶段可以大胆建库删库但进入公司项目后不管是 DDL 还是 DML都要先想清楚影响范围。尤其 DDL很多都没有“撤销”按钮。2. 创建数据库一条 CREATE DATABASE 背后的门道2.1 标准语法与每个参数的含义创建数据库的语法很简单不过简单不代表可以随便写CREATE DATABASE [IF NOT EXISTS] bookstore CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;拆开看中括号里的IF NOT EXISTS表示如果同名库已经存在就不报错。第一次练习时我嫌它多余后来批量脚本跑多了才发现这个保护很有用脚本重复执行不会中断。bookstore是库名。库名最好用小写字母、数字和下划线别用减号、空格也不要跟 SQL 保留字撞车。CHARACTER SET utf8mb4指定字符集COLLATE utf8mb4_general_ci指定排序规则。CHARACTER SET和COLLATE其实可以不写MySQL 会采用配置文件里的默认值。但我们刚学习我建议每次都写出来。理由有两个一是不依赖服务器环境换台机器跑结果一样二是以后从备份文件恢复数据库时你靠SHOW CREATE DATABASE能一眼看出当初的设计意图。2.2 为什么建议选 utf8mb4而不是直接写 utf8这是今天上午我自己最容易踩的坑。很多新手看到utf8就以为万事大吉结果 MySQL 里的utf8是utf8mb3每个字符最多 3 个字节存不了四字节的 emoji就连某些特殊汉字和生僻字也容易出问题。utf8mb4才是完整的 UTF-8 编码每个字符最多 4 个字节能覆盖 emoji、生僻字等更广的字符集。所以从 5.5.3 开始引入后新项目基本都默认utf8mb4。MySQL 8.0 的默认值也已经是utf8mb4但这不代表你可以忽略它。排序规则可以简单理解为字符比较和排序的方式。utf8mb4_general_ci里的ci是 case insensitive 的缩写也就是大小写不敏感适合中英文混合场景。如果你对排序规则有更高要求可以了解utf8mb4_unicode_ci和utf8mb4_0900_ai_ci但初学阶段记住utf8mb4_general_ci已经足够稳妥。再提醒一个连带影响因为utf8mb4每个字符最多占 4 字节所以一个被索引的VARCHAR(255)字段在旧版 InnoDB 里容易触发“索引键太长”的错误Specified key was too long。设计字段长度时得把字符集因素算进去。2.3 查看、切换与修改数据库的基本命令创建完不是结束至少要会三件事看、切、改。-- 查看所有数据库 SHOW DATABASES; -- 查看库的创建语句看字符集和排序规则 SHOW CREATE DATABASE bookstore; -- 切换到目标库 USE bookstore; -- 修改库的字符集 ALTER DATABASE bookstore CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;SHOW DATABASES输出的结果里除了刚建的bookstore还有 MySQL 自带的几个系统库像information_schema、mysql、performance_schema这些不建议乱动。USE这条命令很关键。很多人写完CREATE DATABASE后直接在下一行敲建表语句结果报No database selected原因就是没切库。切库之后你后续的建表、插数、查询才都能落在bookstore里。至于ALTER DATABASE它修改的是库级别的字符集和排序规则不影响已经建好的表。想要让已存在的表也改过来需要单独对每张表执行ALTER TABLE。这个细节我后面还会提到先记上一笔。3. 建表实战把字段类型和约束一次弄明白3.1 常用数据类型怎么选才不容易翻车建表之前先看表结构。今天我用了一张极简的图书表字段设计如下。字段名类型说明idINT UNSIGNED主键自增book_nameVARCHAR(100)书名不可为空authorVARCHAR(50)作者默认“佚名”priceDECIMAL(10,2)定价精确到分publish_dateDATE出版日期可为空stockINT UNSIGNED库存数量默认 0created_atDATETIME入库时间默认当前时间选型要点整数优先看范围。TINYINT占 1 字节INT占 4 字节BIGINT占 8 字节。用户数、商品数这类数据用INT UNSIGNED通常就够无符号范围能到 42 亿左右不要一上来就BIGINT没必要地浪费存储空间。价格不用FLOAT或DOUBLE因为浮点数在二进制存储里有精度误差0.1 加 0.2 不一定等于 0.3。涉及钱用DECIMAL(10,2)总位数 10小数位 2最大能表示 99999999.99覆盖绝大多数定价场景。日期要区分DATE、DATETIME和TIMESTAMP。DATE只存年月日DATETIME存年月日时分秒范围更大TIMESTAMP受数据库时区影响。业务表里记录创建时间用DATETIME比较多。3.2 一条完整的建表语句拆解基于上面的字段设计完整建表语句如下CREATE TABLE IF NOT EXISTS books ( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 主键ID, book_name VARCHAR(100) NOT NULL COMMENT 书名, author VARCHAR(50) NOT NULL DEFAULT 佚名 COMMENT 作者, price DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT 定价, publish_date DATE DEFAULT NULL COMMENT 出版日期, stock INT UNSIGNED NOT NULL DEFAULT 0 COMMENT 库存数量, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 入库时间, PRIMARY KEY (id), UNIQUE KEY uk_book_name_author (book_name, author) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_general_ci COMMENT图书信息表;几个容易忽略的细节NOT NULL说的是字段值不能为空。为什么book_name要非空因为一本书如果连名字都没有这条数据基本没有意义。DEFAULT说的是插入时不显式给值用什么默认值。这里给author设了默认“佚名”给price设了默认 0给stock设了默认 0这样后期插入时可以只填关键字段。AUTO_INCREMENT必须配合索引使用通常就是主键。每次插入时不给 id它会自动加 1。不过要留意事务回滚之后自增值可能不连续这不影响业务判断。COMMENT是注释。给字段加注释刚开始觉得啰嗦三个月后回头看能帮你省下大量回忆时间。唯一联合索引uk_book_name_author约束“书名 作者”不能重复防止不小心插两条一模一样的记录。3.3 约束与存储引擎建表时就要想清楚建表语句末尾写了ENGINEInnoDB。InnoDB 是 MySQL 5.5 之后的默认存储引擎支持事务、行级锁和外键。早期教材里常出现的 MyISAM 不支持事务也不支持外键现在做业务系统基本可以不考虑。约束里的主键、唯一键、非空、默认值我建议在建表时就一起写好不要等数据多了再回头补。原因很简单约束是数据库层面的护栏。没有唯一约束靠程序去判断重复总会有漏网之鱼没有非空约束写入的脏数据就很难从源头拦住。建表成功后可以用下面三条命令确认表结构和创建信息SHOW TABLES; DESC books; SHOW CREATE TABLE books;DESC是DESCRIBE的简写查看字段名、类型、是否允许为空、键信息。做练习时我每建完一张表都会先DESC看一眼再去拼 SQL 语句免得类型想错。4. 增删改查实战INSERT / SELECT / UPDATE / DELETE 的完整跑法4.1 插入数据单行插入与多行批量插入表建好之后先插几条数据。插入语法不难但要小心字段列表和值的顺序一一对应。INSERT INTO books (book_name, author, price, publish_date, stock) VALUES (三体, 刘慈欣, 39.50, 2008-01-01, 100); INSERT INTO books (book_name, author, price, publish_date, stock) VALUES (围城, 钱钟书, 29.00, 1991-02-01, 50), (活着, 余华, 25.00, 2012-08-01, 80);第一条是单行插入第二条是多行插入。多行插入的好处很明显一次网络往返效率比一行一行插高很多。数据量上来以后比如初始化一批测试数据用多行VALUES是最省事的方式。注意我特意没有在主键id和created_at上给值。id由自增生成created_at由CURRENT_TIMESTAMP默认值填充。这样以后写程序时这两个字段基本不用管。如果插入时漏了某个非空字段且该字段没有默认值MySQL 会报Field xxx doesnt have a default value。遇到这个错误先别急着改表多数原因是你没把插入的字段列表写全。4.2 从 SELECT 到 WHERE、ORDER BY、LIMIT 的查询套路查询是 SQL 使用频率最高的一类也是你验证前面建表是否正确的手段。-- 查全部 SELECT * FROM books; -- 指定字段按价格从高到低 SELECT id, book_name, price FROM books ORDER BY price DESC; -- 带条件查询 SELECT id, book_name, price FROM books WHERE price 30 ORDER BY price DESC; -- 分页查询 SELECT id, book_name, price FROM books WHERE price 20 ORDER BY price DESC LIMIT 10;WHERE后面写筛选条件ORDER BY控制排序LIMIT控制返回行数。三者加起来已经能覆盖大多数简单查询场景。我说一下执行顺序并不是先 SELECT 再 WHERE。大概的顺序是先找表FROM再过滤WHERE再分组GROUP BY再过滤分组结果HAVING再排序ORDER BY最后限制行数LIMIT。把这个顺序搞明白你就知道为什么 WHERE 里不能直接用聚合函数别名而 ORDER BY 可以。还有一个容易忽略的组合LIMIT的偏移量。LIMIT 10表示最多返回 10 行LIMIT 10, 20表示跳过前 10 行取 20 行。这个语法在不同数据库里写法不一样但 MySQL 里就是这么记的。如果想顺手算点数据可以加计算列SELECT book_name, price, stock, price * stock AS inventory_value FROM books;inventory_value是计算出来的库存价值不影响表结构。这种“查询时临时计算”的写法很常用。4.3 聚合查询COUNT / SUM / AVG / GROUP BY 的基本用法建表后数据不多但聚合查询的习惯要早养成。SELECT author, COUNT(*) AS book_count, AVG(price) AS avg_price FROM books GROUP BY author ORDER BY book_count DESC;这句的意思是按作者分组统计每个作者的图书数量和平均价格。AS是给查询结果起别名方便阅读。GROUP BY之后SELECT 里能出现的非聚合列一般只能是分组列不然语义会乱。这个规则一开始我不适应踩了几次语法报错后才理解。如果要对分组后的结果再筛选用HAVING比如只保留有 2 本及以上图书的作者SELECT author, COUNT(*) AS book_count FROM books GROUP BY author HAVING COUNT(*) 2;WHERE筛选的是原始行HAVING筛选的是分组后的结果两者不要用混。想统计总数、最大值、最小值对应SUM、MAX、MIN思路和上面一样。4.4 更新与删除动手之前先把 WHERE 看清楚更新数据的写法核心是 SET 后面写要改的字段WHERE 后面写范围。UPDATE books SET stock stock - 1 WHERE id 1;这句模拟卖出一本《三体》库存减 1。写SET stock stock - 1而不是SET stock 99更符合真实业务。你也应该特别注意如果 UPDATE 忘写 WHERE整张表的对应字段都会被更新。这大概是我见过最贵的一行命令。删除数据也一样DELETE FROM books WHERE id 2;删除前我的习惯是先用同条件 SELECT 看一下SELECT * FROM books WHERE id 2;确认这条确实是你要删的再把 SELECT 替换成 DELETE。多花一秒钟能避免删错行。DELETE只是删数据自增计数器不会重置。想清空整表并重置自增用TRUNCATE TABLE books;但它是 DDL执行前更要想清楚而且不能按条件删只能整表清空。5. 高频报错与实战排查这些坑我基本都踩过5.1 常见的语法与结构报错学习阶段最容易遇到的错误整理成一张速查表。报错信息常见原因处理方法ERROR 1049数据库不存在先用 SHOW DATABASES 确认库名ERROR 1050表已存在加 IF NOT EXISTS或 DROP 后重建ERROR 1062唯一索引冲突检查重复字段改为更新或换数据ERROR 1064SQL 语法错误逐字检查关键字、逗号、引号ERROR 1366字符集或编码不匹配确认连接字符集和表字符集一致No database selected没切库执行 USE 库名最常犯的还是ERROR 1064。比如把保留字order当字段名又不加反引号MySQL 就会报语法错。遇到这种我第一个动作是看报错位置前后 5 个字符八成是拼写或符号问题。另外一个是环境差异问题Windows 和 Linux 下表名大小写是否敏感不同。MySQL 在 Windows 上默认不区分表名大小写Linux 上默认区分所以换环境部署时经常莫名其妙找不到表。项目里约定统一小写表名能少很多麻烦。5.2 中文乱码十有八九是字符集链路没打通创建数据库时特意指定了utf8mb4但如果客户端连接字符集不对查询中文依然会乱码。排查思路是这样表字符集、连接字符集、客户端显示字符集三段都要一致。命令行客户端可以先执行SET NAMES utf8mb4;这条命令相当于同时设置了character_set_client、character_set_connection和character_set_results。执行完再跑 SELECT中文通常就正常。图形化工具里一般都有连接字符集选项默认选中utf8mb4即可。如果已经建好表但数据乱码先备份数据再改表字符集最后重新导入。注意单纯的ALTER TABLE books CONVERT TO CHARACTER SET utf8mb4;会修改列字符集但不一定能自动修复已经乱码的数据。乱码问题最好的对策是创建库表时坚决写清楚字符集而不是事后补救。5.3 安全底线SQL 注入与最小权限写 SQL 的时候脑子里要一直有一根安全弦。SQL 注入攻击依然是 Web 应用最大的风险之一网上相关的搜索热度一直很高。作为开发人员正确的做法是和数据库交互时不拼接 SQL 字符串使用参数化查询或预编译语句账号权限最小化只给业务所需的增删改查权限敏感数据不要在日志里明文记录。至于“万能密码绕过登录”这类思路属于危害系统安全的行为不应该去研究更不应该用在任何项目里。把自己的程序做安全才是对用户负责。排查问题的顺序我建议是“先结构、再字符集、再权限”不要一上来就怀疑数据库坏了。多数时候是低级错误比如库名写错、少了个括号、忘记切库。把每一步执行结果看清楚比瞎猜快得多。说回到今天上午这 34 节笔记。我以前图快建表时连字符集都懒得指定后面吃了不少苦头。现在养成两个习惯任何库、任何表创建语句一定完整写清楚字符集、排序规则和注释任何 UPDATE 和 DELETE 之前先跑一条同条件的 SELECT 确认目标。这两个习惯让我少走了很多弯路。希望这节笔记对正在学 MySQL 的你也有同样的作用。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑