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

三条语句:SHOW TABLES 看有哪些表、SHOW CREATE TABLE 看建表语句、DESCRIBE 看列结构。 三条在这里都得换写法:查 sqlite_master 拿表名与建表语句, 用 PRAGMA table_info 拿列信息。 三者的共同点:本质都是「读系统表」,MySQL 只是给了语法糖。 换成 information_schema 的查询,能加条件、能排序、能连表。

📝 本章和前面几章的关系

上一篇建表,这一篇学「验收」:建完怎么看它到底建成什么样了。 这三个动作在真实工作里用得比建表还多: 排查问题时第一件事就是 describe 一下,看列名和类型对不对。

一、show tables:看有哪些表

MySQL 写 SHOW TABLES;——一行一个表名,最省事。 本沙箱报 near "SHOW": syntax error。 等价写法是查 sqlite_master: SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name,给出同样的六个表名。 sqlite_master 是系统表,记着所有表、索引、视图、触发器的定义。 type 那一列区分类型,只挑 table 就是表清单。

二、show create table:看建表语句

MySQL 写 SHOW CREATE TABLE 表名;—— 直接给出当初建这张表用的那句 SQL。 加字段、改默认值时最有用, 因为你得先知道原来写的是什么。 等价写法是查同一张系统表的 sql 列:SELECT sql FROM sqlite_master WHERE name = 'classes'。 拿到的是原始建表语句,连缩进都在。 这一招在做「表结构对比」时特别有用: 两台库的同一张表各 show create 一次,diff 一下就知道差在哪。 这是排查「测试环境好好的、生产环境报错」最快的一招。

三、describe:看列结构

MySQL 写 DESCRIBE 表名;,简写 DESC 表名;——一行一列,给出类型、是否为空、键、默认值。 等价写法是 PRAGMA table_info(表名),Demo 里对上 classes 的四列:id 主键、name 非空, teacher 与 room 都允许为空。 两边给的列数一样、字段名不同: MySQL 是 Field/Type/Null/Key/Default/Extra, 这里是 cid/name/type/notnull/dflt_value/pk。 信息量差不多,多看几遍就熟了。

四、三条语句的共同点:都在读系统表

SHOW TABLES、SHOW CREATE TABLE、DESCRIBE 本质都是查系统表, 只不过 MySQL 给了专门的语法糖。 所以它们也能被「更灵活的写法」替代。 MySQL 那边就是 information_schema: SELECT … FROM information_schema.tables WHERE …—— 能加条件、能排序、能连表,比 SHOW 强得多。 information_schema 是 MySQL 自带的「元数据库」,记着所有库、表、列、索引、权限。 做「找出所有没有主键的表」这种巡检时,只能靠它——SHOW 一条一条看,几百张表根本看不过来。

五、动手 Demo:三条 MySQL 语句先撞错,再给三个等价写法

Demo 四段:先列一遍表,撞一次 SHOW TABLES、撞一次 SHOW CREATE TABLE、撞一次 DESCRIBE, 各给一个等价写法。 每一段都是「先报错、再给能跑的」,对照着看两边语法差在哪。

import _q46 as Q
c = Q.con()

# MySQL 原码,这里三条全报错
for sql in ("SHOW TABLES", "SHOW CREATE TABLE classes", "DESCRIBE classes"):
    try:
        c.execute(sql)
    except Exception as e:
        print("SQL>", sql, "->", e)

# 三个等价写法:都是查系统表
Q.show(c, "SELECT name FROM sqlite_master WHERE type = 'table'")
Q.show(c, "SELECT sql FROM sqlite_master WHERE name = 'classes'")
Q.show(c, "PRAGMA table_info(classes)")

实跑输出:

--------------------------------------------------------------------
第三十八课:查看表——三条 MySQL 语句与三个等价写法
--------------------------------------------------------------------

  看有哪些表
  **MySQL 写**:`SHOW TABLES;`——一行一个表名,最省事。
  SQL> SHOW TABLES
  报错:near "SHOW": syntax error

  SQL> SELECT name FROM sqlite_master WHERE type = 'table' ORDER BY name
  name
  -------------
  classes
  goods
  order_detail
  orders
  scores
  students
  (6 行)

  上面那句就是**本沙箱的等价写法**。 **`sqlite_master` 是系统表,记着所有表、索引、视图的定义。**

  看建表语句
  **MySQL 写**:`SHOW CREATE TABLE 表名;`——**直接给出当初建这张表用的那句 SQL**,加字段、
  改默认值时最有用。
  SQL> SHOW CREATE TABLE classes
  报错:near "SHOW": syntax error

  SQL> SELECT sql FROM sqlite_master WHERE name = 'classes'
  classes 的建表语句:
  CREATE TABLE classes (
          id      INTEGER PRIMARY KEY,
          name    TEXT NOT NULL,
          teacher TEXT,
          room    TEXT)
  (1 行)

  **拿到的是原始建表语句,连缩进都在。** **这一招在做「表结构对比」时特别有用**:
  两台库的同一张表,各 `show create` 一次,diff 一下就知道差在哪。

  看表结构:describe
  **MySQL 写**:
  `DESCRIBE 表名;` 或简写 `DESC 表名;`——**一行一列,给出类型、是否为空、键、默认值。**
  SQL> DESCRIBE classes
  报错:near "DESCRIBE": syntax error

  SQL> PRAGMA table_info(classes)
  cid     name        type        notnull     dflt_value     pk
  ----------------------------------------------------------------------
  0       id          INTEGER     0           NULL           1
  1       name        TEXT        1           NULL           0
  2       teacher     TEXT        0           NULL           0
  3       room        TEXT        0           NULL           0
  (4 行)

  **`PRAGMA table_info` 是本沙箱的等价写法**,六列:序号、列名、类型、是否非空、默认值、是否主键。
  **MySQL 的 `describe` 给的是 `Field`/`Type`/`Null`/`Key`/`Default`/`Extra` 六列**,
  **信息量差不多,字段名不同。** 多看几遍就熟了——**排查问题时第一件事就是 `describe` 一下**。

  三条语句的共同点:都是「读系统表」
  **`SHOW TABLES`、`SHOW CREATE TABLE`、`DESCRIBE` 本质都是查系统表**,
  只不过 MySQL 给了专门的语法糖。
  **所以它们也能被「更灵活的写法」替代**:
  `SELECT … FROM information_schema.tables WHERE …`——**能加条件、能排序、能连表,比 `SHOW` 强。**
  **`information_schema` 是 MySQL 自带的「元数据库」**,记着所有库、表、列、索引、权限。
  **做「找出所有没有主键的表」这种巡检时,只能靠它。**

第一段 SHOW TABLES 报 near "SHOW",等价写法给出六个表名。 第二段 SHOW CREATE TABLE 也报 near "SHOW", 等价写法把 classes 的原始建表语句打出来——连四个空格缩进都在。 第三段 DESCRIBE 报 near "DESCRIBE",PRAGMA table_info 给出四行六列。 第四段没有 SQL,讲的是这三条本质都在读系统表,以及 information_schema。

30 秒实验

  1. 想对比两台库里同一张表的结构差异,用哪条语句最快?为什么?
  2. 要找出「所有没有主键的表」,SHOW TABLES 能办到吗?该用什么?
  3. DESCRIBE 与 PRAGMA table_info 给的六列,哪些信息是等价的?

常见误区

  1. 以为 SHOW CREATE TABLE 给的是「设计要求」。 它给的是数据库实际存下来的定义, 两者经常不一致。
  2. 排查问题不看列结构,直接读代码猜。 先 describe 一下,列名和类型往往一眼就看出来。
  3. 几百张表也一条一条 SHOW。 巡检这类活该用 information_schema 写查询。
自测三问(点开对答案) 1. 三条 MySQL 语句在本沙箱各换成什么? —— `SHOW TABLES` 换成查 `sqlite_master` 的 `name` 列;`SHOW CREATE TABLE` 换成查它的 `sql` 列; `DESCRIBE` 换成 `PRAGMA table_info`。 2. 为什么说这三条语句「本质都在读系统表」? —— 它们都是去元数据里取表名、建表语句、列定义,MySQL 只是包了一层专门的语法。 3. `information_schema` 比 `SHOW` 强在哪? —— 它是普通的表,能加 `WHERE`、能排序、能连表、能聚合,`SHOW` 只能一条一条列。

会看之后才敢改。下一篇 8.5 修改表——改名、加列、改列、删列,四种动作。

相关笔记