💻 第八章 一用就会的数据库
📄 一句话概括

设计先于录入——先定【建哪些表、每张表有哪些列、各列什么类型与约束】,再往里放数据。

📝 本节和前面几节的关系

三方分工明确了,本节回到管家的工作台上:数据库的第一道工序是设计,不是录数据。

一、表格三件套

表:一类事物的集合(学生表、图书表); 列:事物的一个特征(学号、姓名、年级),每列定一个类型; 行:一条具体记录(一名学生)。 这和 6.2 的数组、6.6 的结构体是同一套思维:先定形状,再装数据——只不过这里装进了磁盘。

二、类型与约束

类型按数据本性选:数字用 INTEGER、文字用 TEXT、日期用 DATE——类型是给管家的第一道规矩; 约束把规矩写进表定义:NOT NULL(不许空)、PRIMARY KEY(不许重复)、CHECK(取值范围); 约束写在表上,任何人想违规都会被 DBMS 当场拦下——数据质量的第一道闸。

三、为什么设计必须在前

表结构定下之后,所有数据都按这个模子摆——中途改模子的代价极高(数据要搬家、程序要改口径)。 5.8 说【先在纸上考虑算法】,7.7 说【图纸先行】——数据库同理:设计先行是省钱的铁律。 设计时还要想清楚:哪些信息进哪些表、表之间靠什么关联(8.4、8.5 就是干这个的)。

四、动手 Demo:设计一张学生表

给图书管理设计学生表:定列、定类型、定约束,建成后立刻验收结构。

import sqlite3
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE student ("
            "id INTEGER PRIMARY KEY, "
            "name TEXT NOT NULL, "
            "grade INTEGER)")
for col in con.execute("PRAGMA table_info(student)"):
    print(col)

实跑输出:

--------------------------------------------------------------------
设计数据库——先把表结构定下来
--------------------------------------------------------------------

设计数据库的第一步: 决定【建哪些表、每张表有哪些列】。
给图书管理设计一张【学生表】, 真建一次看结构:

    CREATE TABLE student (id INTEGER PRIMARY KEY, name TEXT NOT NULL, grade INTEGER);

  列名      类型        说明
  --------------------------------------------
  id        INTEGER     学号, 主键(唯一标识)
  name      TEXT        姓名, NOT NULL 不许空
  grade     INTEGER     年级

    建完立刻验收结构:
        0  id       INTEGER  非空=0 主键=1
        1  name     TEXT     非空=1 主键=0
        2  grade    INTEGER  非空=0 主键=0

设计要点: 列名见名知意、类型按数据本性选、约束(主键/非空)写进表定义。
表结构一旦定下, 后面所有数据都按这个模子摆——所以设计要在前面。

PRAGMA table_info 是【查结构】的探头——设计完当场验收,别等录了数据才发现少一列。 【⚠️ 2026 现状】真实项目里表结构用迁移脚本(migration)管理,每一次改动都留有版本记录。

30 秒实验

  1. 给【图书】设计一张表:想清楚需要哪几列、各列什么类型、哪列当主键。
  2. 说出三种约束各自拦下什么样的坏数据。

常见误区

  1. 以为设计就是先建个表凑合用——结构定下后再改,数据要搬家,代价翻倍。
  2. 以为类型随便选——类型错了不仅浪费空间,还会让查找和比较出怪结果。
自测三问(点开对答案) 1. 数据库设计的三个决定? —— 建哪些表、每张表有哪些列、各列的类型与约束。 2. 约束起什么作用? —— 把数据规矩写进表定义,违规数据被 DBMS 当场拦下。 3. 为什么设计要在录数据之前? —— 结构一定,数据都按模子摆,中途改结构代价极高。

相关笔记