看库有三种视角:有哪些、定义是什么、谁在吃磁盘。
SHOW DATABASES 是看列表,SHOW CREATE DATABASE 是看定义。
看占地得查 information_schema,那边才有字节数。
上一篇建库,这一篇看它。
这一篇的三条语句是日常最常用的:接手一个陌生实例,先列库,再看定义,再看占地。
顺序别反:先知道有哪些,再挑重点看。
和第 12 章的关系:查表的空间占用也是同一套办法,只是换成 TABLES。
一、视角一:有哪些
SHOW DATABASES; 列出全部库名,一行一个。
要过滤就加 LIKE:SHOW DATABASES LIKE 'db%';。
它背后就是一条查询:SELECT SCHEMA_NAME FROM information_schema.SCHEMATA;
知道这一点,你就明白为什么它「不用选库也能跑」——它查的是全局字典。
| 语句 | 返回什么 | 能过滤吗 |
|---|---|---|
| SHOW DATABASES | 全部库名 | 只能加 LIKE |
| SHOW DATABASES LIKE 'db%' | 匹配的库名 | 能,但只支持简单通配 |
| SELECT ... FROM information_schema.SCHEMATA | 库名加字符集等列 | 能,随便写 WHERE |
第三行才是「高手写法」:拿到完整两列(库名、默认字符集),一次看全。
二、视角二:定义是什么
SHOW CREATE DATABASE 库名; 会把「重建这个库需要的那句话」打出来。
它包含两件事:字符集、校对规则。
这一句接手陌生库时必跑。
因为「这个库到底是不是 utf8mb4」,光看库名看不出来。
它输出里那串 /*!40100 ... */ 是版本注释:MySQL 5 以上的版本才执行这段。
这是为了让同一份脚本能在老版本上跑也不报错——一种兼容写法,不是乱码。
三、视角三:谁在吃磁盘
SHOW 系列不告诉你字节数,那得查 information_schema.TABLES。
| 想知道的 | 查哪一列 |
|---|---|
| 数据占多少 | DATA_LENGTH |
| 索引占多少 | INDEX_LENGTH |
| 大概多少行 | TABLE_ROWS(统计值,不是精确值) |
| 这张表属于哪个库 | TABLE_SCHEMA |
TABLE_ROWS 那一行要注意:它是统计值,InnoDB 给的是估算。
要精确行数只能 SELECT COUNT(*),大表上还很慢。
第三个容易误解的是 DATA_LENGTH:它包含碎片空间。
删了很多行之后,这个数不会跟着变小——得 OPTIMIZE TABLE 才回收。
四、三条语句怎么配合用
接手一个陌生实例,按这个顺序走,十分钟能摸清家底。
| 步 | 查什么 | 为什么 |
|---|---|---|
| 1 | SHOW DATABASES | 先知道有哪些,别漏了业务库 |
| 2 | SELECT ... FROM SCHEMATA | 一次看到库名和默认字符集 |
| 3 | 按 DATA_LENGTH 排个序 | 找出真正占空间的那几个 |
| 4 | 对大的库跑 SHOW CREATE DATABASE | 确认字符集,避免后面踩坑 |
第四步别省:一个大库如果是三字节的 utf8,后面每一次「存 emoji 报错」都跟它有关。
五、动手 Demo:看库的三种视角:列表、定义、占地
这一课把三种视角各跑一遍。
模型里没有 information_schema,所以占地那一项直接量目录大小。
真机上对应的是查 DATA_LENGTH 和 INDEX_LENGTH。
cat = Catalog(DATA)
for n in ("db_database28", "db_shop", "db_blog"):
cat.create(n)
# 视角一:有哪些
print(cat.databases())
# 视角二:定义是什么
for n in cat.databases():
print("mysql> SHOW CREATE DATABASE", n)
print(cat.show_create(n))
# 视角三:谁在吃磁盘
rows = [[n, len(cat.tables(n)), cat.size(n)] for n in cat.databases()]
rows.sort(key=lambda r: -r[2])
for r in rows:
print(r)
实跑输出:
--------------------------------------------------------------------
第十九课:看库的三种视角:列表、定义、占地
--------------------------------------------------------------------
**教材 4.3 节讲「查看数据库」,其实有三种看法,用途完全不同。**
**看列表是「有哪些」,看定义是「字符集是什么」,看占地是「谁在吃磁盘」。**
一、有哪些:SHOW DATABASES
--------------------------------------------------------------------
[教材原码 · 本沙箱不执行]
| SHOW DATABASES;
| SHOW DATABASES LIKE 'db%';
| SELECT SCHEMA_NAME FROM information_schema.SCHEMATA;
(全部、按模式过滤、以及它背后那条真正的查询)
**真跑一下等价的:列出目录。**
库名
-------------
db_blog
db_database28
db_shop
**MySQL 会多出四个系统库,这里没有——这正是模型和真机的差别。**
二、定义是什么:SHOW CREATE DATABASE
--------------------------------------------------------------------
mysql> SHOW CREATE DATABASE db_blog
CREATE DATABASE `db_blog` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE
utf8mb4_0900_ai_ci */
mysql> SHOW CREATE DATABASE db_database28
CREATE DATABASE `db_database28` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE
utf8mb4_0900_ai_ci */
mysql> SHOW CREATE DATABASE db_shop
CREATE DATABASE `db_shop` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE
utf8mb4_0900_ai_ci */
**这一句最有用:它把「这个库用什么字符集、什么校对规则」一次说清。**
**接手一个陌生的库,先跑这一句。**
三、谁在吃磁盘:按大小排
--------------------------------------------------------------------
库名 表数 字节数
---------------------------
db_shop 1 49207
db_blog 0 55
db_database28 0 55
**三个库都是刚建的,只有一个灌了 2000 行,大小立刻差出两个数量级。**
**所以「库多不多」和「磁盘够不够」是两件事。**
**MySQL 上要看这个得查 `information_schema.TABLES` 的 `DATA_LENGTH` 和 `INDEX_LENGTH` 两列。**
第一段只有三行输出,就是三个库名。
MySQL 上会多出四个系统库,这里没有——这正是模型和真机的差别。
第二段每个库打一行 CREATE DATABASE,长得很像,只有库名不同。
因为三个库都是默认字符集建的。
如果其中一个是 5.7 时代建的,这一行就会露出 utf8 而不是 utf8mb4。
第三段按大小排序,三个库差了两个数量级。
原因只有一个:那个灌了 2000 行的库有真实数据,另外两个是空壳。
最后我补了一句:
MySQL 上要看占地得查 information_schema.TABLES 的 DATA_LENGTH 和 INDEX_LENGTH。
模型里是量目录,真机上是查字典,思路一样。
30 秒实验
- 把
SHOW DATABASES LIKE 'db%'的条件改成LIKE '%shop%',想想结果是什么。 只有db_shop命中。LIKE里%是任意个字符,位置决定匹配方式。 - 在 Demo 里给
db_blog也灌 1000 行,再排一次序。两个库的大小会接近,因为它们的数据量接近。 库名和大小没关系,里面的东西才有关系。 - 想一想:
SHOW CREATE DATABASE输出的那串/*!40100 ... */是注释吗? 是「版本注释」:MySQL 5 以上才执行,以下当注释忽略。 这是为了让一份脚本兼容多个版本,不是写错了。
常见误区
- 「
SHOW DATABASES只给库名,看不到字符集。」 对,所以要看字符集得用SHOW CREATE DATABASE,或者直接查information_schema.SCHEMATA。 - 「
TABLE_ROWS是精确行数。」 是估算值,InnoDB 不会为了回答这个问题去数一遍。要精确只能SELECT COUNT(*)。 - 「删了数据,
DATA_LENGTH会变小。」 不会,它包含碎片空间。 要回收得OPTIMIZE TABLE,那是个重活。
自测三问(点开对答案)
1. `SHOW DATABASES` 背后查的是什么? —— **`information_schema.SCHEMATA`。** **所以它不用选库也能跑——查的是全局字典。** 2. 想知道一个库的字符集,跑哪条语句最快? —— **`SHOW CREATE DATABASE 库名;`** **一行输出里就带着字符集和校对规则。** 3. 要看一张表占多少空间,查哪两列? —— **`DATA_LENGTH` 和 `INDEX_LENGTH`。** **一个管数据,一个管索引,加起来才是这张表的总开销。**下一篇讲 USE:它改的是「这条连接」的状态,不是「数据库」的状态。
搞清这一点,才明白为什么忘了它会报 1046。
- ☐ (本篇完,下一篇 4.4 选择数据库)
相关笔记
- 创建数据库
- 选择数据库
- 45 课 MySQL 必知必会:查数据字典的常用语句
- 🛢️ MySQL从入门到精通 · 索引