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

主键唯一标识表里的每一行,外键存着别家表的主键——拆开的表靠这一对键随时拉手拼回来。

📝 本节和前面几节的关系

上一节把表拆开了,本节回答拆开之后的第一个问题:两张表靠什么互相指认?

一、主键:表里的身份证

主键是能唯一标识一行的那一列(或几列):学号之于学生、订单号之于订单。 两条铁律:唯一(不许重复)、非空(不许缺)——DBMS 亲自把关,想插重复的学号会被当场拒绝。 主键一旦定下,就是这张表对外的【身份证号】——别的表认它,人也可以认它。

二、外键:抄一份身份证号去拉手

外键是 A 表里存着 B 表主键的那一列:借书记录表存学生号,就指向了学生表。 外键表达了【这条记录属于谁】——记录 3 属于学生 2,一读就懂; DBMS 还能用外键约束拦住孤儿数据:指向不存在的学生号的记录,插不进去。

三、关系拼回来

拆表时用编号指过去,查询时按编号拼回来——这个动作就是连接(JOIN); 借书记录表 JOIN 学生表,出来的是【借书记录+对应姓名】的完整视图; 拆得开、拼得回,是关系型数据库名字里【关系】二字的来历。

四、动手 Demo:两表靠主键外键拉手

建学生表与借书记录表,用外键关联,JOIN 查出带姓名的借书记录。

import sqlite3
con = sqlite3.connect(":memory:")
con.execute("CREATE TABLE student (id INTEGER PRIMARY KEY, name TEXT)")
con.execute("CREATE TABLE loan (id INTEGER PRIMARY KEY, "
            "student_id INTEGER REFERENCES student(id), book TEXT)")
con.executemany("INSERT INTO student VALUES (?, ?)", [(1, "波仔"), (2, "小墨")])
con.executemany("INSERT INTO loan VALUES (?, ?, ?)",
                [(1, 1, "三国演义"), (2, 2, "红楼梦")])
sql = ("SELECT student.name, loan.book FROM loan "
       "JOIN student ON loan.student_id = student.id")
for row in con.execute(sql):
    print(row)

实跑输出:

--------------------------------------------------------------------
用主键和外键在表间建立关系
--------------------------------------------------------------------

拆完表, 两张表靠什么拉手? 靠主键和外键。真建两张表看看:

    查一次【连带姓名的借书记录】(两表按外键拉手):
        借书记录1  波仔  《三国演义》
        借书记录2  波仔  《数据结构》
        借书记录3  小墨  《红楼梦》

  键       在哪张表            作用
  ---------------------------------------------------------
  主键     student.id          唯一标识一名学生, 不许重复
  外键     loan.student_id     指向 student.id, 记录属于谁

主键是【身份证号】, 外键是【户口本上写的身份证号】——
有了它俩, 拆开的表还能随时拼回来查询。

JOIN 的条件 loan.student_id = student.id 就是外键指向主键的那根线——关系就是这样拼回的。 外键让【拆表】不再有代价:平时各存各的,要拼时一句 JOIN 就行。

30 秒实验

  1. 给【班级-学生】设计两张表,标出哪列是主键、哪列是外键。
  2. 故意插一条外键指向不存在学生的记录,看看 DBMS 拦不拦。

常见误区

  1. 以为外键就是又存了一遍学生号——存的是【引用】,学生信息仍只在学生表里一份。
  2. 以为主键可以随便选一列——它要唯一且稳定,会变的列当主键后患无穷。
自测三问(点开对答案) 1. 主键的两条铁律? —— 唯一、非空——DBMS 亲自把关。 2. 外键存在哪里、指向哪里? —— 存在 B 表里,存的是 A 表主键的值,指向 A 表。 3. 拆开的表靠什么拼回来? —— JOIN——按外键指向主键的条件连接两表。

相关笔记