🦏 第8章 表的操作
📄 一句话概括

四条语句:CREATE DATABASE/SHOW DATABASES/ALTER DATABASE/DROP DATABASE, 都是 MySQL 专有。 本沙箱一条都跑不了, 四条全报 syntax error——原因不是写错,是引擎里根本没有「库」这个概念。 SQLite 一个文件就是一个库,打开哪个文件就在哪个库里,没有「切库」这个动作。

📝 本章和前面几章的关系

上一篇讲了三个层级,这一篇专门看最上面那层:库。 这一篇是全书写法最特殊的一篇: 它只有教材原码,没有一条能在这里跑通的等价写法。 所以读法是「记住 MySQL 怎么写,理解为什么这里没有」。

一、教材里的四条语句

建库:CREATE DATABASE 库名; 看库:SHOW DATABASES; 改库: ALTER DATABASE 库名 CHARACTER SET utf8mb4; 删库:DROP DATABASE 库名; 外加一条 USE 库名;——切到某个库,之后的语句都作用在它上面。 这五条是 MySQL 里最日常的操作,建库时几乎一定会打一遍。 它们的共同点是「作用在整个库上」,不是某张表、某几行。 所以权限要求也更高——普通账号通常只有某几个库的权限,没有建库删库的权限。

二、逐条撞一次:四条全是语法错

动作 MySQL 写法 本沙箱
建库 CREATE DATABASE school 报语法错
看库 SHOW DATABASES 报语法错
改库 ALTER DATABASE … utf8mb4 报语法错
切库 USE school 报语法错

四条报的都是 syntax error,而且都指在关键字上:DATABASE/SHOW/DATABASE/USE。 这类报错的意思是「这个词我不认识」,不是「参数写错了」。 分清楚这两种报错很重要: 「不认识这个词」说明语法层面就不支持,换个写法也没用;「参数不对」才值得调参数。

三、本沙箱怎么理解「库」

SQLite 是「一个文件就是一个数据库」。 你打开哪个文件,就在哪个库里, 没有「切库」这个动作。 所以那五条语句在这里连存在的必要都没有。 对应关系:MySQL 的「数据库」≈ SQLite 的一个 .db 文件; MySQL 的「表」≈ 那个文件里面的表;MySQL 的「切库」≈ 换一个文件打开。 这不是「SQLite 弱一点」,是两种设计取向: MySQL 一个实例管很多库,所以要库这一层来分组、授权、隔离; SQLite 干脆把「库」交给文件系统管。

四、建库那两个参数,值得单独说

CHARACTER SET utf8mb4:字符集。 utf8mb4 才是「完整的 utf8」,能存 emoji 和生僻字; MySQL 里那个叫 utf8 的其实是残缺版(最多 3 字节),存 emoji 会报错。 COLLATE utf8mb4_0900_ai_ci:排序规则。 结尾 ci 是不区分大小写、ai 是不区分重音,0900 是 Unicode 版本。 这一项决定了 LIKE 和 ORDER BY 的行为——第 5 章撞过这个坑。 建库时不指定,就用服务器默认值。 建议建库时显式写死: 服务器默认值哪天被改了,你的库行为就悄悄变了,而代码一行没动。

五、一个真实存在的风险:DROP DATABASE

DROP DATABASE 库名 会把库里所有表连同数据一起删掉, 而且绝大多数情况下不可回滚。 一条语句,几百张表一起没。 生产环境里这条语句通常被权限直接禁掉,或者要求先把库置成「只读」、确认没有连接在跑。 比它更常见的替代做法:先改名(RENAME 成 school_old_20261030), 观察一周没人喊,再删。 「先改名、后删除」是运维里最省心的习惯之一—— 改错了一个 RENAME 就能改回来,删错了没有回头路。

六、动手 Demo:四条 MySQL 语句,逐条撞一次

Demo 两段:先把教材那四条(外加 USE)逐条执行,看它们各报什么错; 再把 SQLite 的「一个文件一个库」讲清楚。 这一段的目的不是学会建库,是学会认「语法不支持」这类报错。

import _q46 as Q
c = Q.con()

# 教材里的四条,逐条撞一次
for sql in ("CREATE DATABASE school",
            "SHOW DATABASES",
            "ALTER DATABASE school CHARACTER SET utf8mb4",
            "USE school"):
    try:
        c.execute(sql)
    except Exception as e:
        print("SQL>", sql)
        print("  报错:", e)

实跑输出:

--------------------------------------------------------------------
第三十六课:库的操作——教材原码,本沙箱不执行
--------------------------------------------------------------------

  教材里的四条语句
  **建库**:`CREATE DATABASE 库名;`
  **看库**:`SHOW DATABASES;`
  **改库**:`ALTER DATABASE 库名 CHARACTER SET utf8mb4;`
  **删库**:`DROP DATABASE 库名;`

  **这四条在 MySQL 里是日常操作,在本沙箱一条都跑不了。** 下面逐条撞一次,看报什么。

  逐条撞一次
  SQL> CREATE DATABASE school
  报错:near "DATABASE": syntax error
  SQL> SHOW DATABASES
  报错:near "SHOW": syntax error
  SQL> ALTER DATABASE school CHARACTER SET utf8mb4
  报错:near "DATABASE": syntax error
  SQL> USE school
  报错:near "USE": syntax error

  **四条全是 `syntax error`。** **原因不是写错了,是「本沙箱的引擎里没有库这个概念」。**

  本沙箱怎么理解「库」
  **SQLite 是「一个文件就是一个数据库」。** 你打开哪个文件,就在哪个库里,
  **没有「切库」这个动作。**
  **对应关系**:MySQL 的「数据库」≈ SQLite 的一个 `.db` 文件;
  MySQL 的「表」≈ SQLite 里那个文件中的表。
  **所以 8.2 这一篇的内容,本沙箱只能「讲」不能「演」。**
  **教材里这四条照原样记,实操时在 MySQL 上跑。**

  建库时那两个参数,值得单独说
  **`CHARACTER SET utf8mb4`**:字符集。 **`utf8mb4` 才是「完整的 utf8」**,能存 emoji 和生僻字;
  MySQL 里那个叫 `utf8` 的其实是残缺版(最多 3 字节),**存 emoji 会报错。**
  **`COLLATE utf8mb4_0900_ai_ci`**:排序规则。 结尾 `ci` 是不区分大小写、`ai` 是不区分重音。
  **这一项决定了 `LIKE` 和 `ORDER BY` 的行为**,第 5 章撞过。
  **建库时不指定,就用服务器默认值。** **建议建库时显式写死**——
  **服务器默认值哪天被改了,你的库行为就悄悄变了。**

  一个真实存在的风险:DROP DATABASE
  **`DROP DATABASE 库名` 会把库里所有表连同数据一起删掉**,**而且绝大多数情况下不可回滚。**
  **生产环境里这条语句通常被权限直接禁掉**,**或者要求先进「只读」状态、确认没有连接。**
  **比它更常见的替代做法**:改名(先 `RENAME` 成 `xxx_old_20261030`),
  **观察一周没人喊,再删。** **「先改名、后删除」是运维里最省心的习惯之一。**

四条全是 syntax error。 报错位置分别在 DATABASE、SHOW、DATABASE、 USE 上——都是关键字不认识。 注意 ALTER DATABASE 报的是 near DATABASE,不是 near CHARACTER, 说明引擎在第二个词就停下了,后面的字符集参数根本没读到。 后面三段没有 SQL,讲的是 SQLite 的「一个文件一个库」、utf8mb4 与 utf8 的区别、 以及 DROP DATABASE 的风险。

30 秒实验

  1. SHOW DATABASES 报 near "SHOW": syntax error,这句话说明是语法错了还是参数错了?
  2. 在 MySQL 里建库写 utf8,存一个 emoji 会怎样?为什么?
  3. 要删掉一个不再使用的库,比 DROP DATABASE 更稳的做法是什么?

常见误区

  1. 建库时用 utf8 而不是 utf8mb4。 那个 utf8 最多三字节,存 emoji 直接报错, 事后改字符集要重建表。
  2. 以为 SQLite 报语法错是「少装了什么」。 是引擎设计上就没有库这一层,装什么都补不上。
  3. 上来就 DROP DATABASE。 一条语句几百张表一起没,先改名观察一周,成本几乎为零。
自测三问(点开对答案) 1. 本沙箱为什么跑不了 `CREATE DATABASE`? —— SQLite 一个文件就是一个数据库,引擎里根本没有「库」这一层,所以这些关键字不认识。 2. `utf8mb4` 和 MySQL 里的 `utf8` 差在哪? —— `utf8mb4` 是完整四字节,能存 emoji 和生僻字;MySQL 的 `utf8` 最多三字节,存 emoji 会报错。 3. `COLLATE` 影响什么? —— 影响比较与排序规则,比如是否区分大小写、是否区分重音,直接决定 `LIKE` 和 `ORDER BY` 的结果。

库这一层看完了,下一篇回到表:8.3 建表——列名、类型、属性,三样都要写清楚。

相关笔记