装完 MySQL,里面已经躺着四个系统库,不是空的。
其中 information_schema 一个字节都不占,它全是现算的视图。
一个库里能装七种对象,只有表真正占数据空间。
图形工具左边那棵树,就是查数据字典画出来的。
第 3 章讲的是「用工具点」,这一章开始讲「用 SQL 敲」——两条路到同一个地方。 它是第 6 章(表)之前的准备:先把「库」这一层认清,再往下建表。 这一篇提到的七种对象,会在后面七章里一个一个展开。 现在只需要知道它们都存在同一个库里、地位平行。
一、先分清三个词:数据库、库、表
日常说话里这三个词经常混着用,写 SQL 时混了会出错。
| 词 | 指什么 | 在 SQL 里怎么出现 |
|---|---|---|
| 数据库(DBMS) | MySQL 这个软件 | 不出现,它是服务端 |
| 库(database/schema) | 一组表的容器 | CREATE DATABASE 库名 |
| 表(table) | 真正存数据的地方 | CREATE TABLE 库名.表名 |
一句话:MySQL 管着很多库,库管着很多表,表管着很多行。
四层结构,一层套一层。
「schema」这个词在 MySQL 里和「database」是同义词。
所以 CREATE SCHEMA 和 CREATE DATABASE 效果完全一样。
但别的数据库不一定这样——Oracle 里 schema 是「用户」,是另一回事。
二、装完自带的四个系统库
第一次 SHOW DATABASES 会看到四个陌生的库,它们不是垃圾,是 MySQL 自己的家当。
| 库名 | 存什么 | 能不能删 |
|---|---|---|
| mysql | 账号、权限、口令散列、时区 | 删了没人能登录 |
| information_schema | 所有库表结构的元数据 | 删不掉,它是虚拟的 |
| performance_schema | 运行时的性能计数 | 能关,别删 |
| sys | 把上面两个库包成好读的视图 | 能删,但排查脚本靠它 |
第二行最容易被误解:information_schema 里没有数据文件。
你查它一次,它去问一遍真正的元数据,现算给你看。
所以 SHOW DATABASES 并不是「读了一个列表文件」,它就是一条查 information_schema 的语句。
这一点在第 4.3 节还会用到。
顺带一个实用结论:想知道一张表占多大,别去看文件大小,去查 information_schema.TABLES。
三、一个库里能装七种对象
「库」不只是「表的集合」,它能装七种东西。
| 对象 | 是什么 | 占不占数据空间 |
|---|---|---|
| 表 TABLE | 真正存数据的二维表 | 占 |
| 视图 VIEW | 存下来的一句 SELECT | 不占,只存语句 |
| 索引 INDEX | 为了查得快而建的排序结构 | 占,而且可能很大 |
| 存储过程 PROCEDURE | 一堆 SQL 打包成一个名字 | 不占,只存文本 |
| 函数 FUNCTION | 有返回值的存储过程 | 不占 |
| 触发器 TRIGGER | 某张表被改动时自动跑 | 不占 |
| 事件 EVENT | 定时任务 | 不占 |
七种里只有表和索引占数据空间,其余五种都是「逻辑对象」。 这一点在容量规划时很有用:一个库里有几百个视图,不代表它大。 它们的关系也不是并列的:索引挂在表上,触发器挂在表上。 视图可以引用表,存储过程和函数可以操作表。 表是中心,其余都绕着它转。
四、数据字典:数据库自己知道自己有什么
MySQL 把「我有哪些库、哪些表、每张表什么结构」记在一个地方,叫数据字典。
8.0 之前它是散在一堆 .frm 文件里的,8.0 起合并进了 InnoDB 的系统表。
SQLite 也有一份,叫 sqlite_master,一张表就把三种对象全装下了。
Demo 里真查了一次,输出里那三行就是数据库的「自我认知」。
这件事的实际价值是:图形工具的左侧树、SHOW TABLES、库里的表数,都从这一个地方来。
会查它,等于会自己造工具。
五、动手 Demo:一个 MySQL 装完,里面已经躺着四个库
这一课把四个系统库、七种对象摆清楚,然后真看一眼「数据字典」。 沙箱没有 MySQL,但数据字典这件事 SQLite 也有,可以真查。
import sqlite3
# 建一个库(在 SQLite 里就是一个目录加一个 db.sqlite)
cat.create("db_database28")
cat.use("db_database28")
c = cat.conn()
c.execute("CREATE TABLE tb_goods (id INTEGER PRIMARY KEY, name TEXT)")
c.execute("CREATE VIEW v_goods AS SELECT id, name FROM tb_goods")
c.execute("CREATE INDEX i_name ON tb_goods (name)")
# 数据字典:数据库自己知道自己有什么
for r in c.execute("SELECT type, name FROM sqlite_master "
"ORDER BY type, name"):
print(r)
实跑输出:
--------------------------------------------------------------------
第十七课:一个 MySQL 装完,里面已经躺着四个库
--------------------------------------------------------------------
**教材 4.1 节先讲「数据库里有什么」。**
**很多人以为装完 MySQL 是一个空壳,其实它自带四个系统库。**
**这一课把这四个库、以及「库里能装哪几种对象」摆清楚。**
**沙箱没有 MySQL,但「数据字典」这件事 SQLite 也有,可以真看。**
一、装完自带的四个库
--------------------------------------------------------------------
库名 存什么 能不能删
------------------------------------------------------------------------------------
mysql 账号、权限、口令散列、时区 删了没人能登录
information_schema 所有库表结构的元数据(视图,不占磁盘) 删不掉,是虚拟的
performance_schema 运行时的性能计数 能关,别删
sys 把上面两个库包成好读的视图 能删,但很多排查脚本靠它
**第二个最容易误解:`information_schema` 里没有数据文件。**
**它是「按需现算出来的视图」,你查它一次,它去问一遍真正的元数据。**
**所以 `SHOW DATABASES` 其实就是查它。**
**这一点在 4.3 节会再撞上。**
二、库里能装七种对象
--------------------------------------------------------------------
对象 是什么 在哪一章
---------------------------------------------------------
表(TABLE) 真正存数据的二维表 第 6 章
视图(VIEW) 存下来的一句 SELECT 第 13 章
索引(INDEX) 为了查得快而建的排序结构 第 12 章
存储过程(PROCEDURE) 一堆 SQL 打包成一个名字 第 14 章
函数(FUNCTION) 有返回值的存储过程 第 14 章
触发器(TRIGGER) 某张表被改动时自动跑 第 16 章
事件(EVENT) 定时任务 第 17 章
**七个里只有表占数据空间,其余六个都是「逻辑对象」。**
**视图不存数据,索引存的是排好序的指针,存储过程存的是语句文本。**
三、数据字典长什么样:真看一眼
--------------------------------------------------------------------
**在 SQLite 里,这张「字典表」叫 `sqlite_master`;MySQL 里对应 `information_schema`。**
SELECT type, name
FROM sqlite_master
ORDER BY type, name
类型 名字
---------------
index i_name
table tb_goods
view v_goods
**三种对象都在里面,`type` 那一列就是它们的类别。**
**MySQL 的 `information_schema.TABLES` 里也是这么一行一个对象。**
**这就是「数据库自己知道自己有什么」的地方。**
**所有图形工具的左侧树,都是查这张表画出来的。**
第一段建了三样东西:一张表、一个视图、一个索引。
这正是「一个库里能装七种对象」的前三种。
第二段查出来的三行,就是数据字典的全部内容:table、view、index。
注意那个视图也在里面——它虽然不存数据,但它是个「对象」,得登记。
MySQL 里对应的查询是 SELECT * FROM information_schema.TABLES WHERE TABLE_SCHEMA = '库名'。
多了一堆列,但结构一样:一行一个对象。
最后那张表列了七种对象里哪几个占空间。
视图不占、存储过程不占、触发器不占——这三样再多,也不会让磁盘变满。
30 秒实验
- 在 Demo 里再建一个触发器或者一张临时表,回头看
sqlite_master多没多一行。 触发器会多一行(type是trigger),临时表不会——它在另一个字典里。 - 把
ORDER BY type, name改成ORDER BY name,看顺序怎么变。 两种排序各有用途:按类型是「清点家当」,按名字是「找人」。 - 想一想:为什么
information_schema删不掉?因为它不是真的库,是一层视图。 删一个不存在的东西,自然无从下手。
常见误区
- 「装完 MySQL 是一个空数据库。」
不是,自带四个系统库。
其中
mysql那个库删了,root 就登不上来了。 - 「库就是表的集合。」 它还能装视图、索引、存储过程、函数、触发器、事件。 只说「表的集合」,后面看到视图就懵了。
- 「
information_schema占了不少磁盘吧。」 它一个字节都不占,全是现算的视图。 查它一次,它就去问一遍真正的元数据。
自测三问(点开对答案)
1. MySQL 里 database 和 schema 是同一个东西吗? —— **是。`CREATE SCHEMA` 和 `CREATE DATABASE` 完全等价。** **但别的数据库不一定——Oracle 的 schema 是「用户」。** 2. 一个库里能装哪七种对象? —— **表、视图、索引、存储过程、函数、触发器、事件。** **只有表和索引占数据空间。** 3. `SHOW DATABASES` 背后查的是什么? —— **查 `information_schema.SCHEMATA`。** **它不是读某个列表文件,就是一条普通的查询。**下一篇真动手:建库。 四种写法,差别全在「库已存在」那一刻——以及为什么脚本必须写成幂等的。
- ☐ (本篇完,下一篇 4.2 创建数据库)
相关笔记
- 数据库操作管理
- 创建数据库
- 15 课 数据库基础:库、表、视图的原理
- 🛢️ MySQL从入门到精通 · 索引