
前言
日常开发中,我们几乎离不开数据库,那对于日常开发来说,为什么不直接用普通文件存数据?MySQL 数据库服务器、数据库、表三者是什么关系?SQL 语句分为哪几大类?存储引擎又到底是什么?
本文从为什么需要数据库开始,带你认识主流数据库,掌握 MySQL 基础操作,理清整体架构、SQL 分类以及存储引擎的核心知识点,适合零基础入门学习。
读完本文,你将理解数据库存在的原因与 MySQL 的整体架构,并能独立完成建库、建表、改表、备份恢复等全部基础操作——这是通往后续 SQL 增删改查、索引优化、事务隔离的必经之路。
我们写的所有程序,数据都只活在内存里,进程一退出就灰飞烟灭。要让数据真正"落地",就得让它落到磁盘上;而要让落到磁盘上的数据还能被高效地查出来、改得了、并发安全地访问,光靠自己 fopen + fwrite 去操控文件系统是远远不够的。这时,数据库就该登场了。
一、数据库基础认识
1.1 什么是数据库
数据库是计算机里一套规范化的数据存储管理方案。底层依旧依赖磁盘上的文件保存信息,但不再像普通文本文件那样随意存放数据。它把信息按固定结构整理归类,应用程序可以向它发起请求,完成数据的查找、添加、更新与删除;同时可以支持多个程序同时读写,减少文件直接读写带来的数据错乱、查询缓慢等问题,为网站、软件这类业务程序提供可靠的数据持久化能力。
从理论层面分析,数据库是存放在外存上,具备结构化、可共享、数据与程序相互独立特性的关联数据集合。依靠数据库管理系统 DBMS 作为中间层,对数据实施统一管控,提供 DDL 数据定义、DML 数据操纵、实体完整性、参照完整性约束、并发控制、权限管理以及故障恢复等机制,降低数据冗余,保障事务执行时的数据一致性,弥补传统文件系统在数据共享与可靠性方面的短板,是信息系统构建数据层的核心基础设施。
数据库建立在文件系统之上,底层靠文件持久化数据,可以说数据库是对普通文件的封装,增加索引、并发、事务、权限等能力,解决裸用文件管理大量数据的各种缺陷。而我们平时说的 MySQL、Oracle、SQL Server,准确叫 数据库管理系统(DBMS),是用来管理数据库的软件,负责增删改查、权限、存储。
1.2 为什么需要数据库
可能很多人会有疑问:存储数据,用文件不就行了吗?为什么还要费劲搞一个数据库出来?

答案也很简单,文件确实能存数据,但只能"存",不能"管"。文件存储有四大硬伤,每一个都直击开发者的痛点:
- 安全性问题:文件就裸躺在磁盘上,任何人只要有权限就能打开、复制、篡改。没有访问控制,没有加密,没有审计——一份客户名单和一份系统配置文件在文件系统眼里没有任何区别。
- 不利于数据查询和管理:假设你要在 100 万条订单记录里找出"2026 年 6 月、金额大于 500 元、状态为已支付"的订单。用文件存储,你只能自己写代码遍历整个文件逐行比对——时间复杂度 O(n),还得自己处理字段切分、类型转换、格式校验。而数据库一条
SELECT ... WHERE就搞定了,还能走索引做到 O(log n)。 - 不利于存储海量数据:文件系统是按"文件"为粒度管理的,一个几 GB 的大文件读写、备份、迁移都极其笨重。数据库则把数据切分成页、块等内部结构,配合索引和缓存,能支撑 TB 甚至 PB 级别的数据。
- 文件在程序中控制不方便:多个进程/线程同时写同一个文件,会出现数据竞争、写覆盖、读到一半的状态等问题,你必须自己实现锁机制。而数据库把这些并发控制、事务原子性全部内置了。
总的来说,文件是"数据仓库",数据库是"数据管家"。 仓库只负责把东西堆起来,管家负责登记、检索、防盗、对账。当你的数据量小到一个人能手工管理时,文件足够;一旦数据规模、并发、安全、一致性任意一项上了量,就必须请"管家"了。

顺带说一句,数据库的存储介质也不只是磁盘——内存数据库(如 Redis)是把数据放内存里换取极致速度,磁盘数据库把数据落盘换取持久性。二者各有所长,现代系统往往是"内存缓存 + 磁盘数据库"的组合拳。
1.3 主流数据库一览——没有最好,只有最合适
市面上数据库五花八门,初学者最容易犯的错就是"哪个最牛就学哪个"。其实每种数据库都是为了解决特定场景的问题而生的,选择的关键是匹配业务需求:
| 数据库 | 出身 | 定位与特点 | 典型场景 |
|---|---|---|---|
| SQL Server | 微软 | 与 .NET 生态深度绑定,中大型项目 | 企业内部管理系统、.NET 技术栈项目 |
| Oracle | 甲骨文 | 功能最全、最贵,适合大型项目与复杂业务逻辑,但并发一般不如 MySQL | 银行、电信、大型国企 |
| MySQL | 甲骨文(原 MySQL AB) | 全球最受欢迎的开源数据库,并发性能好,不适合过于复杂的业务逻辑,简单 SQL 处理效果极佳 | 电商、SNS 社交、论坛 |
| PostgreSQL | 加州大学伯克利分校 | 功能强大的开源关系型数据库,免费使用、修改和分发 | 需要复杂查询、JSON、地理数据的场景 |
| SQLite | 开源社区 | 轻量级嵌入式数据库,遵守 ACID,整个引擎就是一个小型 C 库,占用资源极低(嵌入式设备几百 KB 内存即可) | 手机 App、浏览器、嵌入式设备 |
| H2 | 开源 | Java 编写的嵌入式数据库,本身只是一个类库,可直接嵌入应用项目 | Java 应用的单元测试、小型桌面应用 |

我们选择介绍的数据库是 MySQL,为什么选择它呢?因为它卡在了一个绝佳的生态位上:开源免费 + 并发性能强 + 足够简单 + 社区庞大。绝大多数中小型互联网公司、绝大多数校招面试题、绝大多数个人项目,用的都是它。掌握了 MySQL,你就拿到了进入后端开发世界的通用门票。
二、认识MySQL
2.1 MySQL基础
MySQL 采用经典的客户端/服务器(C/S)架构。所谓"安装 MySQL",装的是一个服务器程序(后台守护进程 mysqld),它负责真正地管理磁盘上的数据。而我们要操作数据,得通过一个客户端程序去连接它、发指令。所以当我们安装了MySQL后,使用时要连接上对应的服务端,Linux中我们可以通过下面的命令来启动我们的MySQL:
mysql -h 127.0.0.1 -P 3306 -u root -p
这条命令的每个参数都有明确含义:
| 参数 | 含义 | 默认值(省略时) |
|---|---|---|
-h | host,要连接的服务器地址 | 省略则连本机(localhost) |
-P | port,服务器的端口号(注意是大写 P) | 省略则连 3306 (MySQL服务器默认的端口号) |
-u | user,登录用户名 | 必须指定 |
-p | password,提示输入密码(小写 p, 后面通常不直接跟密码) | — |
我们所使用的就是MySQL的客户端,所以上述命令的作用就是用MySQL客户端去连接对应的MySQL服务器。MySQL是一个常驻后台的系统服务,所以在安装后我们需要先让它跑起来,这样才能通过客户端去连接服务器。
我们可以通过各种命令去控制MySQL服务的启动、停止、暂停等:
sudo systemctl start mysql
sudo systemctl stop mysql
sudo systemctl restart mysql
sudo systemctl enable mysql # 设置开机自启
这些服务控制命令很重要,因为很多配置改动(比如修改了 my.ini 配置文件、调整了字符集)都需要重启服务才能生效,你重启客户端是没有用的。理解"MySQL 是一个服务进程"这个事实,能帮你解释很多诡异现象——比如"我改了配置怎么没反应",十有八九是忘了重启服务。
下图就是MySQL在我们的计算机中存在的关系表:

我们通过前面的认识基本上也可以理解它们,下面再逐层解释一下:
- 客户端(client):客户端自己并不存数据,它只是一个"遥控器",负责把你的 SQL 语句发给服务器、再把结果取回来显示。常见的客户端有
mysql命令行、Navicat、DataGrip,以及程序里用的 JDBC 和各种 ORM 框架。 - 服务器:一台机器上安装的 MySQL 管理程序,一个服务器实例可以管理多个数据库。
- 数据库(database / schema):逻辑上的"数据容器",一般一个应用对应一个数据库。比如电商系统建一个
shop库,博客系统建一个blog库。 - 表(table):数据库里存具体数据的结构,一个实体对应一张表。比如
shop库里会有user表、order表、product表。

打个比方:客户端是你的手机,服务器是银行的数据中心,数据库是数据中心里的一个个保险库,表是保险库里的一排排抽屉。 你用手机 App(客户端)下单,指令通过网络传到银行数据中心(服务器),数据中心找到对应的保险库(数据库),再打开具体的抽屉(表)存取数据。客户端、服务器、数据库、表,四者各司其职,缺一不可。
2.2 MySQL架构
MySQL 为什么能被那么多人选择?它的架构设计、语言设计、存储引擎设计分别给出了答案。

MySQL 的架构是可移植 + 插件式存储引擎。
MySQL 有一个很了不起的特性:可移植性。它几乎能在当前所有的操作系统上运行——Unix/Linux、Windows、Mac、Solaris。虽然各系统的底层实现细节不同,但 MySQL 基本能保证各个平台上物理体系结构的一致性。这意味着你在一台 Windows 机器上学到的知识、写的 SQL,迁移到生产环境的 Linux 服务器上依然原封不动地成立。
存储引擎(Storage Engine) 定义的是:数据库管理系统如何存储数据、如何为存储的数据建立索引、如何更新和查询数据——一句话,它是"数据落地"这一层的具体技术实现。
MySQL 最核心的设计就是插件式存储引擎:它把"SQL 解析、执行"这一上层逻辑,和"数据怎么存、索引怎么建"这一底层实现解耦了。上层逻辑统一,底层可以像插 U 盘一样插拔不同的存储引擎。这意味着同一张表,你可以选择用 InnoDB 存(支持事务、行级锁),也可以选择用 MyISAM 存(查询快、不支持事务),只需要在建表时加一个 engine 参数即可。
我们可以在MySQL中查看当前 MySQL 支持哪些存储引擎:
show engines;
执行后会列出所有引擎及其支持情况:

我们将其中最核心的两个进行一下对比:
| 对比维度 | InnoDB | MyISAM |
|---|---|---|
| 事务支持 | ✅ 支持(ACID) | ❌ 不支持 |
| 锁粒度 | 行级锁(并发性能好) | 表级锁(并发性能差) |
| 外键 | ✅ 支持 | ❌ 不支持 |
| 崩溃恢复 | ✅ 强(redo/undo 日志) | ❌ 弱(易损坏) |
| 全文索引 | 5.6 后支持 | ✅ 支持 |
| 默认引擎 | ✅ MySQL 5.5+ 的默认引擎 | 旧版默认引擎 |
| 典型场景 | 需要事务、并发写多的业务 | 只读为主、查询密集的报表 |
现代MySQL 的搜索引擎默认都是用 InnoDB,这是为什么呢?
因为互联网业务的核心诉求是"高并发 + 不丢数据"。MyISAM 的表级锁意味着一个写操作会锁住整张表,并发场景下性能灾难;而它不记日志,服务器一断电就可能损坏数据文件。InnoDB 用行级锁 + 事务日志 + 崩溃恢复,把这两块都补齐了——代价是稍微复杂一点、占一点额外空间,但换来的是数据的安心。
2.3 SQL分类
很多初学者把 SQL 当成"一种语言",其实 SQL 内部按职责分成了四类。理解这个分类,你就理解了"什么时候该用什么语句":
| 分类 | 全称 | 中文名 | 作用 | 代表指令 |
|---|---|---|---|---|
| DDL | Data Definition Language | 数据定义语言 | 维护数据的结构(库、表的结构) | create、drop、alter |
| DML | Data Manipulation Language | 数据操纵语言 | 对数据本身进行操作 | insert、delete、update |
| DQL | Data Query Language | 数据查询语言 | 查询数据(从 DML 中细分出来) | select |
| DCL | Data Control Language | 数据控制语言 | 权限管理和事务控制 | grant、revoke、commit |
记忆口诀:DDL 管结构,DML 管数据,DQL 管查询,DCL 管权限。 对应到现实:DDL 是"盖房子"(create table),DML 是"往里搬家具"(insert),DQL 是"找东西"(select),DCL 是"给谁配钥匙"(grant)。四者职责边界清晰,互不越界。
这一分类也暗示了本文的章节划分:DDL 是主角(库的操作、表的操作本质上都是 DDL),因为它是后续一切数据操作的前提——结构没定义好,数据往哪儿放?
三、库的操作
现在我们已经简单的认识了数据库以及MySQL,对于我们程序员来说,其实最重要的还是如何正确的使用数据库,接下来就让我们来进行库的操作,库的核心操作就四个:建(CREATE)、查(SHOW)、改(ALTER)、删(DROP),一般来说,我们一个应用程序对应一个库,下面让我们进行演示:
3.1 创建数据库——CREATE DATABASE
建库的完整语法:
CREATE DATABASE [IF NOT EXISTS] db_name
[create_specification [, create_specification] ...];
create_specification:
[DEFAULT] CHARACTER SET charset_name
[DEFAULT] COLLATE collation_name
语法约定说明:
- 大写的是关键字,小写的是你要替换的占位符
[]里的都是可选项,可以省略CHARACTER SET:指定数据库采用的字符集COLLATE:指定数据库字符集的校验规则
在MySQL中的SQL语句是大小写不敏感的,所以对于关键字我们可以用大写,也可以用小写。后面的演示我都将使用小写来进行操作。
IF NOT EXISTS的意思就是如果我们所创建的数据库不存在再创建,如果存在就不创建了。来看下面的示例:

我们可以通过show databases查看当前MySQL中存在的数据库:

可以看到,当创建的数据库存在时,因为我们加了IF NOT EXISTS,所以语句也会正常执行,只是不会再创建对应的数据库了,如果不加,就会发生报错:

在 Linux 中,执行建库语句后,MySQL 会在指定数据存放目录 (datadir) 下,自动创建一个和数据库名同名的操作系统目录。我们可以通过
show variables like 'datadir';语句来查看这个目录的地址:
进入该目录后我们就可以看到我们创建的数据库其对应的目录:
上面我们提到了创建数据库时还有CHARACTER SET和COLLATE两个参数,它们分别代表了字符集和校验规则;当我们不显示指定时会使用MySQL默认的。那什么是字符集与校验规则呢?
3.2 字符集与校验规则——一个管"怎么存",一个管"怎么比"
字符集和校验规则是两个容易混淆的概念,一定要分清:
- 字符集(character set):控制数据用什么编码存储。比如
utf8能存中文,gbk也能存中文但编码方式不同。字符集决定"存进去的是什么字节"。 - 校验规则(collation):控制数据如何比较和排序。同样都是 utf8 字符集,可以有
utf8_general_ci(不区分大小写)和utf8_bin(按二进制区分大小写)两种校验规则。校验规则决定"两个字符串怎么比大小"。
查看系统默认字符集和校验规则:
show variables like 'character_set_database';

对于字符集,相信大家应该不陌生,因为这和我们常说的编码很像;MySQL 中的
utf8本质是utf8mb3,仅支持最多 3 字节字符,无法存储 emoji 等 4 字节 Unicode 字符;utf8mb4才是完整的标准 UTF-8 实现,所以 MySQL8.0 默认使用utf8mb4。
show variables like 'collation_database';

我们也可以通过SQL语句查看 MySQL 支持的所有字符集和校验规则:
show charset; -- 支持的字符集
show collation; -- 支持的校验规则
我们可以在建库时显示指定想要用的字符集和校验规则,只要数据库支持就可以。
字符集决定数据在磁盘上以何种编码存储。如果读取数据时使用的编码和存储编码不一致,就会出现乱码;
建库时选错校验规则,会导致查询结果"看起来是错的"。 比如你的用户名系统希望
Admin和admin是两个不同的人,就必须用区分大小写的校验规则;反过来,如果希望搜索时不区分大小写,就得用_ci(case-insensitive)结尾的规则。校验规则不是可有可无的细节,它直接决定业务逻辑的正确性。
3.3 查看与操纵数据库——SHOW、ALTER、DROP
建好库之后,我们需要能查看它、修改它、删除它。
-
查看有哪些数据库:
show databases;上面的SQL语句能查看当前MySQL服务器中所有的数据库:

-
查看某个库的创建语句:
show create database 数据库名;我们查看一下刚才创建的
test_base数据库:show create database test_base;可以看到:

它的作用是查看创建该数据库时的 SQL 语句,同时可以直接看到该数据库默认的字符集与校验规则。
这里藏着两个细节:
- 数据库名字用反引号
`包裹,是为了防止数据库名刚好是 MySQL 的关键字(比如你起名叫select,不用反引号就会语法错误)。 /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */不是注释,它的含义是:当前 MySQL 版本号大于 4.01 时,就执行这句话。这是一种版本条件编译的语法糖,让备份文件在不同版本间兼容。
- 数据库名字用反引号
-
修改数据库(主要改字符集/校验规则):
ALTER DATABASE db_name [alter_spacification [, alter_spacification] ...]; alter_spacification: [DEFAULT] CHARACTER SET charset_name [DEFAULT] COLLATE collation_name注意:对数据库的修改主要指修改字符集和校验规则,因为库本身没有太多可改的属性。例如我们把
test_base库的字符集改成gbk:alter database test_base charset = gbk;可以看到对应数据库的字符集已经改为
gbk了:

-
删除数据库:
DROP DATABASE [IF EXISTS] db_name;一般来说不要随意删除数据库,因为删除的后果极其严重,务必牢记:
- 数据库内部看不到对应的数据库了
- 对应的数据库文件夹被删除,级联删除,里面的所有数据表全部被删
千万不要随意删除数据库。 这是不可逆操作——
DROP DATABASE没有"回收站",删了就真的没了,连带着里面所有表、所有数据、所有索引一起消失。生产环境执行 DROP 之前,必须三思、必须备份、最好先在测试库演练一遍。
3.4 备份与恢复——mysqldump 与 source
既然删库这么危险,那"备份"就是作为程序员的我们最重要的保命技能了。MySQL 提供了 mysqldump 工具来做逻辑备份。这个工具不在MySQL客户端内部,需要我们在OS中使用:
-
备份整个数据库:
备份整个数据库我们需要用到的命令是:
# mysqldump -P端口 -u 用户名 -p密码 -B 数据库名 > 备份文件路径 mysqldump -P3306 -u root -p123456 -B mytest > D:/mytest.sql其实它就相当于把我们指定的数据库重定向到指定的文件中,这也是备份的本意;打开生成的
mytest.sql文件你会发现,里面装的其实是把我们整个创建数据库、建表、导入数据的语句都拼成了文本。所以mysqldump本质是"把数据翻译成 SQL 脚本"——这既是它的优点(可读、可移植、跨版本兼容),也是它的特点(备份大库时文件巨大、速度一般)。备份时的
-B选项的作用是创建对应的数据库,也就是生成对应的sql文件中包含CREATE DATABASE语句,如果不带-B选项,那么在我们使用该sql文件还原数据库时需要先创建对应的数据库才能进行使用。-P端口可以省略,如果没有修改MySQL的默认端口号。我们来演示一下备份的过程:

备份后我们就可以在指定的目录下找到对应的sql文件:

因为我们只是建了一个空的数据库,没有建表和添加数据,所有这个
test.sql文件中的内容很少:
-
还原数据库:
有了sql文件,那接下来要做的就是在MySQL中使用sql文件,还原它所对应的数据库;这里我们需要用到
source命令,source是 MySQL 客户端里执行脚本文件的命令,它会逐条执行文件里的 SQL语句;下面让我们删除之前的数据库,使用备份生成sql文件恢复它:

现在我们已经删除了对应的数据库,下面就是恢复:

可以看到对应的数据库已经被恢复了。
如果备份时没有带
-B参数,那么生成的 SQL 文件里就不包含CREATE DATABASE语句。还原时就不能直接source,而必须先手动create database建一个空库,再use这个库,最后才source还原。带了-B参数的文件自带建库语句,可以直接source。 -
其他:
除了备份一个数据库,我们还可以只备份一个数据库中某几个表:
# 备份单张/多张表(不备份整个库) mysqldump -u root -p 数据库名 表名1 表名2 > ./mytest.sql当然,我们还可以同时备份多个数据库:
# 同时备份多个数据库 mysqldump -u root -p -B 数据库名1 数据库名2 > ./backup.sql
3.5 查看连接情况——show processlist
MySQL数据库是一个网络服务进程,我们可以通过客户端访问指定主机上的MySQL服务器,所以在启动客户端时我们可以通过-h和-P选项来指定 IP 地址和端口号。因此一个MySQL服务器上可以同时被若干个客户端所连接,这时我们可以通过show processlist;查看所有连接到当前 MySQL 服务器的用户、来源主机、正在执行的命令、状态等信息:

show processlist 的实用价值在于安全排查和性能诊断:如果查出来某个用户不是你正常登录的(比如一个陌生的 IP、陌生的用户名),那你的数据库很可能被入侵了。以后如果发现数据库突然变慢,也可以用这个命令看看是不是有异常连接在占着资源。
四、表的操作

库建好了,下一步就是在库里建表。表是真正存放数据的地方,也是我们日常打交道最多的对象。表的操作比库复杂——因为它有"结构"(列名、类型、约束),而结构是可以被反复修改的。下面让我们先来进行表的增删查操作:
4.1 创建表——CREATE TABLE
建表的完整语法:
CREATE TABLE table_name (
field1 datatype,
field2 datatype,
field3 datatype
) character set 字符集 collate 校验规则 engine 存储引擎;
语法说明:
field表示列名datatype表示列的类型(int、varchar、date 等)character set指定字符集,不指定则以所在数据库的字符集为准collate指定校验规则,不指定则以所在数据库的校验规则为准engine指定存储引擎
关于MySQL的数据类型,可期待下篇文章,下一篇将详细介绍MySQL的数据类型。
建表的语句也很简单,下面我们就简单的创建一个表:
进行表操作时,需要先选择数据库,我们用use 数据库名;来指定数据库:

那如何查看当前使用的哪个数据库呢?我们可以使用MySQL内置的函数database()查看:
准备工作完成后,我们就可以正式的建表了:
这样一个简单的user表就创建成功了;
create table users (
id int comment '用户编号',
name varchar(20) comment '用户名',
birthday date comment '用户生日'
) character set utf8 engine MyISAM;
我们来看一下我们的建表语句,有几个注意的点:
comment是列注释,是给程序员看的说明文字,不影响数据存储,但对团队协作和维护至关重要——在复杂的表中,半年后回来看表,没有注释你根本不知道某一列存的是什么。engine可以指定存储引擎,在建表时我们可以指定存储引擎,不同的存储引擎在底层存放数据的方式不一样。
存储引擎决定表文件的形态:上面这张表用了 MyISAM 引擎,建表后会在数据目录里生成三个文件:
| 文件 | 后缀 | 作用 |
|---|---|---|
users.frm | frm | 表结构定义 |
users.MYD | MYD(MY Data) | 表数据 |
users.MYI | MYI(MY Index) | 表索引 |
这就是"插件式存储引擎"最直观的体现:不同的存储引擎,创建表时生成的文件不一样。 如果你改用 InnoDB 引擎建表(
engine InnoDB),会发现它通常只生成一个.ibd文件(数据和索引都装在里面),外带一个共享的.frm结构文件。数据怎么落盘、索引怎么组织,完全由引擎说了算——上层 SQL 语法一模一样。
4.2 查看表结构——DESC
我们创建了表之后,在插入数据时肯定要知道表的结构,这样才能正确的插入数据,查看表结构我们用下面的语句来进行:
desc 表名; -- desc 是 describe 的缩写
执行 desc users; 会输出:
这张表每一列的含义,是理解表结构的钥匙:
| 列名 | 含义 |
|---|---|
| Field | 字段名(列名) |
| Type | 字段类型 |
| Null | 是否允许为 NULL(YES=允许,NO=不允许) |
| Key | 是否是索引键(PRI=主键、UNI=唯一、MUL=普通索引) |
| Default | 默认值 |
| Extra | 附加信息(如 auto_increment 自增) |
这样我们就可以查看表对应的结构了;
通过上面查询的表结构中,我们可以看到表对应的列名和它的数据类型,以及一些是否为空、键值、默认值等,但没有我们在建表时通过comment添加的注释,那该如何查看呢?我们可以通过show create table 表名查看:

我们可以通过该语句查看完整的建表 SQL,包含字段、主键、索引、引擎、字符集、注释。
\G是竖向排版,把每一列单独一行展示,方便阅读长内容,优化命令行阅读体验。
两者都可以查看表结构,它们的对比如下面的表格所示:
| 项目 | desc 表名;(等价describe) | show create table 表名\G; |
|---|---|---|
| 核心作用 | 只查看字段结构(列名、类型、是否为空、主键、默认值、注释) | 查看完整建表定义,包含字段 + 索引 + 引擎 + 字符集 + 表注释 |
| 输出内容 | 只列每一列信息,看不到索引定义、存储引擎、字符集 | 完整CREATE TABLE源码,主键 / 普通索引 / 唯一索引、ENGINE、CHARSET、collate 全部都有 |
| 适用场景 | 快速看有哪些字段、字段类型,日常简单查看表列 | 迁移表、核对存储引擎、排查字符集、查看索引、复制建表 SQL |
| 格式 | 横向表格 | \G竖向展示,适合长语句阅 |
我们还可以通过show tables查看当前数据库中的所有表:

4.3 修改表——ALTER TABLE
在项目实际开发中,表结构不是一成不变的——改字段名、改字段大小、改字段类型、改表的字符集、改存储引擎,甚至加字段、删字段。表结构不是一建完就定死的,ALTER TABLE 就是用来修改表结构的。
先给 users 表插入两条数据,方便观察后续修改对数据的影响,我们通过insert into进行插入数据(具体的操作解释见后边的文章):
insert into user (id, name, birth) values (1, 'zs', '2005-01-11'), (2, 'ls', '2005-02-22');
我们来进行一下插入:

插入完成后我们可以通过查询语句来查看当前表中的数据(后面的文章会详细介绍查询语句):
接下来进行我们的修改操作:
-
添加字段(ADD)——新增一个保存图片路径的字段:
ALTER TABLE tablename ADD (column datatype [DEFAULT expr][, column datatype]...); -- 在 birth 字段之后添加 address 字段 alter table user add address varchar(100) comment '图片路径' after birth;after birth指定新字段插入的位置(放在 birth 列之后)。插入新字段后,原来表中的数据不受影响,新字段的值对已有行都是 NULL:
-
修改字段类型(MODIFY)——把
id类型改为varchar(20):ALTER TABLE tablename MODIFY (column datatype [DEFAULT expr][, column datatype]...); alter table user modify id varchar(20);MySQL 允许
ALTER TABLE修改字段类型,但有前提:原有数据必须能安全转换成目标类型,转换失败就直接报错,不允许修改。这里int转为varchar,只要varchar长度足够,就没有问题:
-
删除字段(DROP)——删除
adress列:ALTER TABLE tablename DROP (column); alter table user drop adress;删除字段一定要小心:
DROP column删掉的不只是字段定义,该字段对应的所有列数据都会一起消失,且不可恢复。这跟DROP DATABASE一样是不可逆操作,删之前务必确认这份数据真的不要了:
-
修改表名(RENAME):
alter table user rename to employee; -- 把 users 表改名为 employee(to 可省略)查看改完名字后的结果:

-
修改字段名(CHANGE)——把
name改成xingming:alter table employee change name xingming varchar(60);这里有一个容易踩的坑:
change需要完整写出新字段的定义(包括类型),不能只写个新名字。上面这条语句里varchar(60)不能省——因为change的语义是"重命名 + 重定义类型"一步到位。如果你只想改字段名不想动类型,也得把原类型原样抄一遍:
可以看到,
change的作用和modify有相似之处,只是change不仅能改字段类型,也能改字段名称;而modify只能修改字段类型!
4.4 删除表——DROP TABLE
删除表的完整语法:
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name] ...;
drop table t1;
和删库一样,删表也是级联且不可逆的——表里的所有数据、索引、约束一并消失。IF EXISTS 是一个贴心的保护参数:表不存在时不会报错,脚本里常用它来保证幂等性。

五、常见问题

我们来汇总一下上面会出现的常见问题,这些坑,几乎每个 MySQL 初学者都栽过。提前看过,能帮你省下大量排查时间:
- SQL 语句忘记加分号,命令"卡住"不动
- 现象:输入
show databases回车后,光标换行到->却没有任何输出,终端像是死机了。
- 原因:MySQL 用分号
;作为一条语句的结束标志。没加分号,MySQL 会认为你还没输完,进入"续行等待"状态,等你继续输入。 - 解决:在
->提示符后补一个;再回车即可。如果输入到一半想放弃,输入\c可以清空当前未完成的语句。
- 现象:输入
- 建库时忽略校验规则,查询结果"莫名其妙"
- 现象:明明表里有
Admin和admin两条数据,where name='admin'却查出两条;或者排序结果不符合直觉。 - 原因:数据库默认的校验规则是
utf8_general_ci,不区分大小写(_ci= case insensitive)。它把Admin和admin当成同一个值。 - 解决:如果业务要求区分大小写(如用户名、密码这类敏感字段),在建库/建表时指定
utf8_bin或_bin结尾的区分大小写规则;同时,重要字段(如密码)在应用层也应做哈希后存储,而不是依赖大小写敏感性来区分。
- 现象:明明表里有
- 备份时忘了带
-B参数,还原时傻眼- 现象:用
mysqldump -u root -p 数据库名 > xxx.sql备份,还原时source xxx.sql报错"数据库不存在"。
- 原因:不带
-B参数时,生成的 SQL 文件里不包含CREATE DATABASE语句,它假设目标库已经存在了。 - 解决:还原前先手动建库、切库,再
source。
- 现象:用
- 把 DROP 当"撤销"用,数据灰飞烟灭
- 现象:手滑执行了
drop database或alter table ... drop column,数据瞬间消失,想找回时才发现没有备份。 - 原因:
DROP系列操作是级联、不可逆的——删库会连表一起删,删字段会连该列数据一起删,且没有回收站机制。 - 解决:
- 任何 DROP 操作前,先
mysqldump备份; - 生产环境养成"先在测试库演练,再上生产"的习惯;
- 用
IF EXISTS保护幂等,但不要因此麻痹大意——IF EXISTS只防止"表不存在时报错",不防止"表存在时被删"。
- 任何 DROP 操作前,先
- 现象:手滑执行了
六、总结

让我们用一个"是什么 → 为什么 → 怎么做"的框架,把全文串起来:
| 维度 | 核心内容 | 一句话记忆 |
|---|---|---|
| 是什么 | 数据库是"数据管家",解决文件存储的四大痛点(安全、查询、海量、并发控制) | 文件是仓库,数据库是管家 |
| 为什么 | 三层结构(服务器→数据库→表)让数据组织清晰;SQL 四分类(DDL/DML/DQL/DCL)让职责分明;插件式存储引擎让数据落地可插拔 | 结构分层、语言分职、引擎插件化 |
| 怎么做 | 库操作(CREATE/SHOW/ALTER/DROP + 备份恢复)、表操作(CREATE/DESC/ALTER/DROP) | 建查改删,四字贯穿 |
最关键的两个认知,请你带走:
- 字符集管"怎么存",校验规则管"怎么比"。 建库建表时显式指定字符集(生产用
utf8mb4)和校验规则(按业务决定大小写敏感性),别等数据出了问题才回头改。 - DDL 决定结构,结构决定一切。 库和表的操作本质都是 DDL——结构定义好,后续的
insert/select才有地方安放。而结构一旦上线,修改(ALTER)和删除(DROP)都要慎之又慎,因为它们可能影响或摧毁已有数据。
下一章我们将对MySQL数据库的数据类型进行讲解,敬请期待!
尾声
本章讲解就到此结束了,若有纰漏或不足之处欢迎大家在评论区留言或者私信,同时也欢迎各位一起探讨学习。感谢您的观看!
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/2302_80243065/article/details/168232653







