If you're seeing this message, it means we're having trouble loading external resources on our website.

如果你被网页过滤器挡住,请确保域名*.kastatic.org*.kasandbox.org 没有被阻止.

主要内容

将数据拆分到相关的数据表

到目前为止,我们只是一次处理一个表格,看看可以从表格中找出哪些有趣的数据。但实际上,大多数时候数据都分布在多个表格中,这些表格在某些方面是相互“关联”的。
举个例子,假如这是个学生考试成绩表,表中含有电子邮箱以便老师能给家长发送成绩:
姓名邮箱科目成绩
皮皮兔peter@rabbit.com营养学95
爱丽丝alice@wonderland.com营养学92
皮皮兔peter@rabbit.com化学85
爱丽丝alice@wonderland.com化学95
我们还有一个表格来记录学生读过的书:
姓名书名作者
皮皮兔海底两万里儒勒·凡尔纳
皮皮兔哈利波特与魔法石J.K.罗琳
爱丽丝奇妙动物在哪里J.K.罗琳
爱丽丝哈利波特与魔法石J.K.罗琳
还有第三个表来记录学生信息:
学生ID邮箱电话生日
1皮兔peter@rabbit.com555-66662001-05-10
2丽丝alice@wonderland.com555-44442001-04-02
你怎么看这些表格?你会随意修改它们吗?
对这些表格应该有个很重要的认识:这里面有很多互相有关系的数据。这些表格都跟特定的学生有关,而且其中有很多重复的数据。如果相同的数据出现在不同的表格中,会发生很有趣的事情。
比如,如果某个学生的邮箱地址改了该怎么办?我们该修改哪个表格呢?
我们需要改学生信息表,但考试成绩表中也有这个信息啊,而且我们需要修改这个学生的 每一行 记录中的邮箱地址。
更可取的做法是确保每一个特定的数据列只保存在 一个地方 ,这样需要改动的地方就更少,出错的可能性也更小。这样的话,我们需要确保有办法把不同表格中的数据关联起来,之后我们会提到这方面。
比如我们决定从考试成绩表中删除邮箱地址数据,因为在学生信息表中已经有邮箱地址了。这样就变成:
姓名科目成绩
皮皮兔营养学95
爱丽丝营养学92
皮皮兔化学85
爱丽丝化学95
怎么找到每个学生的邮箱地址?我们可以从学生信息表中用学生姓名找到记录该学生的行。那如果两个学生名字一样呢?(你知道中国有多少张伟,有多少王艳?)我们不能依赖名字来查找学生,而且说实在的,我们永远不能依赖类似名字这样的数据做唯一识别。
所以最好是删掉 姓名 ,替换成 学生ID,因为这是唯一识别码。
学生ID科目成绩
1营养学95
2营养学92
1化学85
2化学95
我们同样来修改读书记录表,用 学生ID 来替换 姓名
学生ID书名作者
1海底两万里儒勒·凡尔纳
1哈利波特与魔法石J.K.罗琳
2奇妙动物在哪里J.K.罗琳
2哈利波特与魔法石J.K.罗琳
注意到《哈利波特与魔法石》这本书的书名和作者重复了两次吗?这提醒了我们需要把表格继续拆分成多个关联的表格,这样如果有本书的名字要修改,我们就不需要更新多个地方了。
我们单独设立书籍信息表:
书籍ID书名作者
1海底两万里儒勒·凡尔纳
2哈利波特与魔法石J.K.罗琳
3奇妙动物在哪里J.K.罗琳
这样我们的学生读书记录表就变成了:
学生ID书籍ID
11
12
23
22
我知道,相比于把所有信息塞到每一行中的旧表,这个表格很不易读。但是,表格的设计往往不是为了方便人阅读——而是为了最易维护和最不易出错。在许多情况下,最好将数据拆分为多个关联表格,以便减少重复数据和需要更新位置。
知道如何用 SQL 处理已拆分为多个关联表格的数据,并在需要时将数据重新组合在一起,这一点非常重要。我们通过一个名为”联接“的概念来执行此操作,这就是我接下来要向你展示的。

想加入讨论吗?

尚无帖子。
你会英语吗?单击此处查看更多可汗学院英文版的讨论.