ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

关系数据库入门:表、主键外键与 SQL Join 实战(Data-Science-For-Beginners 第 5 课)

关系数据库入门:表、主键外键与 SQL Join 实战(Data-Science-For-Beginners 第 5 课) 关系数据库入门表、主键外键与 SQL Join 实战Data-Science-For-Beginners 第 5 课【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners本篇指南以 Data-Science-For-Beginners 课程「Working with Data: Relational Databases」为核心系统讲解关系数据库的核心概念——表、行与列、主键PK与外键FK并手把手演示如何使用 SQL 的SELECT、WHERE与INNER JOIN从多张表中检索和合并数据。读完本文你将能够理解为什么单表会带来数据冗余掌握用主外键拆表建模的思路并能在 VS Code 中直接操作仓库自带、真实可查询的 airports.db 完成实战练习。一切从表开始关系数据库的最小单元关系数据库Relational Database最核心的组成单元是表Table。如果你用过 Excel 等电子表格软件就已经熟悉它的基本形态一张表由若干行Row和列Column构成。行中存放的是我们真正关心的数据如一座城市的名字、某年的降水量而列则描述这些数据的含义——这类描述数据的数据有时也被称为元数据Metadata。以课程文档中的示例为例我们用一张表存放城市信息CityCountryTokyoJapanAtlantaUnited StatesAucklandNew Zealand这里的列名City、Country就是元数据它说明每一行里存储的分别是什么而每一行则是对一座城市的完整描述。关系数据库正是建立在这个列 行的朴素原理之上它的强大之处在于允许把信息分散到多张表中从而支持更复杂的数据、避免重复并让数据探索方式更加灵活。单表方案的短板冗余与僵化当我们只有三座城市时单表看起来无可挑剔。可一旦数据量增长问题就会暴露出来。课程文档以年度降水量为例展开了两个典型反例。反例一纵向重复行。如果我们在同一张表里按年份追加降水数据为了保存 Tokio 三年2018、2019、2020的数据城市名和国家名就必须重复出现三遍CityCountryYearAmountTokyoJapan20201690TokyoJapan20191874TokyoJapan20181445这种重复既浪费存储空间也会带来更新隐患——比如城市名拼写变更时你必须同步修改所有重复行否则数据就会不一致。反例二横向扩展列。换个思路把年份变成列CityCountry201820192020TokyoJapan144518741690AtlantaUnited States177911111683AucklandNew Zealand13869421176虽然避免了行的重复却引入了新的麻烦每新增一个年份就必须修改表结构添加新列而且当数据量变大后把年份作为列会让检索某一年、按年份求和这类计算变得非常别扭。两个反例指向同一个结论我们需要多张表以及表与表之间的关系Relationship。通过把数据拆分才能避免重复并获得操作上的灵活性。关系的两个支点主键与外键拆分数据之前必须先解决一个关键问题如何唯一标识一张表中的一行答案是主键Primary Key缩写PK。✅ 课程文档特别提醒本课中id与primary key两个词会交替使用这一概念同样适用于你稍后接触的 DataFrame——DataFrame 虽然不用主键这个术语但行为上高度相似。主键是用于标识表中某一行唯一记录的值。虽然理论上可以拿业务值当主键例如直接用城市名但实践中主键几乎总是数字或其它与业务无关的标识符——因为我们不希望主键发生改变一旦主键变化所有依赖它的关系都会被破坏。大多数数据库会自动生成自增主键。于是课程把城市信息整理成一张带city_id主键的cities表city_idCityCountry1TokyoJapan2AtlantaUnited States3AucklandNew Zealand存放降水量的rainfall表则不再重复城市名与国家而是只保存城市的引用rainfall_idcity_idYearAmount11201814452120191874312020169042201817795220191111622020168373201813868320199429320201176注意rainfall表中的city_id列它存放的值指向cities表的主键。在关系数据库术语中这种引用另一张表主键的列被称为外键Foreign Key缩写 FK。你可以把它理解成一个引用或指针——例如city_id为 1 的记录就指向城市 Tokio。同时新表也保留了自己的主键rainfall_id因为每一张表都应该有自己的主键。[!NOTE] 外键常被缩写为FK主键常被缩写为PK。用 SQL 检索数据SELECT 与 WHERE数据拆到两张表后如何把需要的信息取回来答案是 SQL——结构化查询语言Structured Query Language。像 MySQL、SQL Server、Oracle 这类关系数据库都支持 SQL它是检索和修改关系数据库中数据的标准语言SQL 常被读作 sequel。检索数据的基础命令是SELECT在SELECT后列出你想看的列在FROM后列出这些列所在的表。如果只想显示所有城市名称SELECT city FROM cities; -- Output: -- Tokyo -- Atlanta -- Auckland[!NOTE] SQL 语法不区分大小写select与SELECT等价但列名、表名在某些数据库上可能区分大小写。因此编程中最好的习惯是默认一切都区分大小写。写 SQL 时业内惯例是把关键字统一写成大写。上面的查询会返回所有城市。如果我们只关心新西兰的城市呢这时需要过滤条件SQL 的关键字是WHERE——即在条件为真的地方SELECT city FROM cities WHERE country New Zealand; -- Output: -- AucklandWHERE接受一个布尔表达式只有满足条件的行才会出现在结果中。合并两张表INNER JOIN到目前为止我们都是从单表取数。现在要把cities和rainfall的数据合并展示这就要用到Join连接。Join 的本质是在两张表之间缝合起来把一张表的某列值与另一张表某列的值一一匹配。本课的例子是用rainfall表的city_id与cities表的city_id做匹配从而把每条降水记录关联回它的城市。这里使用的连接类型是INNER JOIN内连接如果某行在另一张表中找不到匹配则不会出现在结果里。本例中每座城市都有降水数据所以全部行都会显示。先看第一步——仅指定连接列把两表缝合SELECT cities.city, rainfall.amount FROM cities INNER JOIN rainfall ON cities.city_id rainfall.city_id说明SELECT后以表名.列名的方式限定列避免两张表出现同名列时产生歧义ON后面给出两表连接的缝线条件。原文档示例中两列之间需以逗号分隔这是 SQL 的合法写法。在此基础上追加WHERE只保留 2019 年的降水数据SELECT cities.city, rainfall.amount FROM cities INNER JOIN rainfall ON cities.city_id rainfall.city_id WHERE rainfall.year 2019 -- Output -- city | amount -- -------- | ------ -- Tokyo | 1874 -- Atlanta | 1111 -- Auckland | 942可以看到INNER JOIN负责横向拼表WHERE负责纵向筛行两者组合即可完成按城市关联、按年份过滤的典型分析需求。这正是关系数据库的威力所在数据虽然分散在多张表但通过连接可以随时按需重组进行展示、计算与各种灵活操作。实战用 airports.db 练习连接查询理论讲完现在进入可运行的实战环节。课程为这一课配套了真实数据库 airports.db基于 SQLite 构建其中包含英国与爱尔兰的机场数据。完整练习说明见 作业文档下面给出从零开始的操作路径与参考答案。准备环境VS Code SQLite 扩展安装 Visual Studio Code在其扩展市场安装SQLite 扩展SQLiteby alexcvzz该扩展提供了图形化的数据库浏览与查询入口。[!NOTE] 更详细的扩展使用说明请查阅扩展自身的文档页面。打开数据库并建立查询窗口打开 Visual Studio Code按Ctrl-Shift-PMac 上为Cmd-Shift-P输入并执行SQLite: Open database选择Choose database from file打开上文提到的 airports.db打开数据库后界面可能没有明显变化此时再按Ctrl-Shift-PMac 上为Cmd-Shift-P输入并执行SQLite: New query新建查询窗口在查询窗口中编写 SQL用Ctrl-Shift-QMac 上为Cmd-Shift-Q执行。[!NOTE] 数据库的 schema结构设计决定了你能查询什么。airports库包含两张表Cities存放英国与爱尔兰的城市列表Airports存放机场列表。由于一座城市可能拥有多个机场所以拆成两张表通过外键关联——这正是本文前半部分讲解的建模思路。数据库结构速览对照数据库实际定义可通过PRAGMA table_info查看两张表的结构如下Citiesid (PK, integer)city (text)country (text)Airportsid (PK, integer)name (text)code (text)city_id (FK → Cities.id)从源码结构看airports.db 实际表定义Airports.city_id即为指向Cities.id的外键Airports表中目前存有 181 条机场记录。四道练习与参考答案以下查询结果均基于仓库中的 airports.db 实际执行验证可直接在 VS Code 查询窗口复现。练习 1列出Cities表中的全部城市名SELECT city FROM Cities;练习 2列出Cities表中位于爱尔兰Ireland的全部城市SELECT city FROM Cities WHERE country Ireland;执行后共返回 16 行包括 Cork、Galway、Dublin、Shannon、Kerry 等爱尔兰城市。练习 3列出所有机场的名称及其所在城市和国家SELECT a.name, c.city, c.country FROM Airports a INNER JOIN Cities c ON a.city_id c.id;这里用a、c作为表的别名Alias并以外键a.city_id c.id作为连接条件。结果中的部分行例如Belfast International Airport | Belfast | United Kingdom George Best Belfast City Airport | Belfast | United Kingdom Birmingham International Airport | Birmingham | United Kingdom练习 4找出伦敦London, United Kingdom的全部机场SELECT a.name, a.code FROM Airports a INNER JOIN Cities c ON a.city_id c.id WHERE c.city London AND c.country United Kingdom;这一步同时用到了本文的全部知识点INNER JOIN关联两张表WHERE过滤目标城市最终返回伦敦的 6 个机场及其 ICAO 代码namecodeLondon Luton AirportEGGWLondon Gatwick AirportEGKKLondon City AirportEGLCLondon Heathrow AirportEGLLLondon Stansted AirportEGSSLondon HeliportEGLW可以看到练习 4 与前文cities rainfall 按 2019 年过滤的 JOIN 思路完全一致先连接、后过滤。掌握了SELECT、FROM、WHERE、INNER JOIN、ON这五个要素你就已经掌握了关系数据库最核心的日常操作。总结关系数据库的核心思想是把信息拆分到多张表中再在需要展示与分析时通过 Join重组起来。这种拆-合的循环带来了极高的灵活性使计算和数据操作不再受限于单表结构。通过本课你已经理解了表、行、列与元数据的关系单表方案的两种典型缺陷行重复、列扩展导致的冗余与僵化用主键PK唯一标识行、用外键FK跨表引用从而建立表间关系用SELECT ... FROM检索、用WHERE过滤、用INNER JOIN ... ON合并两张表在真实数据库 airports.db 上完成从环境搭建到四道连接查询练习的完整流程。下一步你可以进入 第 6 课非关系型数据对比 NoSQL 与关系模型的差异也可以在仓库中继续学习 用 Python 处理数据把 SQL 思维迁移到 DataFrame 中。本文对应的英文原版文档见 05-relational-databases 英文 README德语译本即 当前文档。【免费下载链接】Data-Science-For-Beginners10 Weeks, 20 Lessons, Data Science for All!项目地址: https://gitcode.com/GitHub_Trending/da/Data-Science-For-Beginners创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表