数据库 频道

一个数据分析师的自述:戏说数据建模3NF

我最近很多朋友咨询范式的定义,因此,在这里我尝试解释以下,希望能够激励其他人提供更好的东西……

让我们想象一下不同的情况,有人问这样的问题:“数据建模和 3NF 是什么?” (似乎真的想要一个答案)。这可能是我口头回应的方式,可能会借助白板或稿纸等东西来涂鸦。

电梯里的执行官说:

“我们持有的数据就像业务模型。数据建模是一组学科,旨在使模型尽可能有用,并有助于避免混乱和歧义。这是成为数据驱动型公司的关键组成部分。”

正在开会的经理说:

“我们选择保存数据的方式将影响我们可以用它做什么以及它的稳健程度。认真对待数据的公司也认真对待数据建模。

规范化建模(包括 3NF)旨在确保:(a) 您知道拥有一组不同的“事物”,例如单个客户或产品,(b) 您在任何时候掌握的有关这些事物的事实都是明确的- 例如如名称、地址或尺寸,并且(c) 您了解每个“事物”与其他“事物”的关系,例如客户与产品的关系。

举一个简单的例子,当我们存储客户订单时,我们不会存储每个订单的所有产品详细信息,因为我们最终可能会持有相互冲突的产品详细信息版本……”

有兴趣的同事在喝咖啡休息时说:

“我们选择保存数据的方式将影响我们可以用它做什么以及它的稳健程度。我们持有的数据就像我们所处的现实世界的模型。数据建模是使模型变得有用、灵活和明确的艺术。

数据建模者用来测试模型的基本规则集称为“标准化”。这是一个纯粹的数学术语,但不用担心,您不需要数学学位来理解和使用这些规则。这些规则通常被概括为“表或数据集中的每个事实都依赖于键 (1NF)、整个键 (2NF),并且只依赖于键 (3NF) ”。

让我给你规则和一些例子。想象一个包含多个字段或列的数据表:

1NF表示必须有一个键——一个或多个唯一标识表中行的字段。1NF 还说,一旦你有了一个主键,你就知道在其他每个字段中会找到什么(除非它是空的——这是一种特殊情况,你可以定义是否允许空)。因此,每个字段中应该只有一个“事实”,并且需要知道所需的数据类型- 例如数字、日期或字符串。

一个简单的例子:您是否使用过依赖电子邮件地址作为主键的服务,但也将您的姓名和出生日期挂在其上?假设您和您的配偶共享该电子邮件地址 - 现在,他们将在姓名和出生日期字段中保存哪些事实?

当键由多个字段或列组成时,2NF是相关的。它表示表中的其他列必须依赖于所有键列,而不仅仅是子集。

3NF假设任何 2NF 问题都已修复,但也表示其他列必须直接依赖于键,而不是通过其他列。

范式化还有几种其他的形式,但 90% 的情况下,达到 3NF 实际上可以解决所有问题。

为什么这很重要?它确保您能够一致地捕获系统中“事物”的所有信息。

例子:

让我们举个例子 - 假设我们正在经营一家带有活动的歌舞表演,对于每个活动,客户可以预订一张或多张桌子。

预订的唯一主键是什么?嗯,这不是事件加客户——这显然不是唯一的。也许是事件和桌子?现在我们就这样假设每个事件仅在一个日期进行。

那么,我们在这里违反了什么规则?有些字段仅依赖于主键字段之一 - 例如事件的日期和桌子的大小-破坏了 2NF。还有一个字段 Address 取决于 Customer —打破了 3NF。

以这种方式保存数据的问题是

a)我们可能会不一致地记录它们,例如桌子 23 的大小或 Dietrich 女士的地址;

b)没有明确的位置来记录与预订无关的事实——其他顾客的地址、未使用的桌子的大小、或任何预订之前的活动日期。解决这些问题被称为“规范化”,并且几乎总是涉及创建更多表。例如:

当然,识别和解决这些问题可能会引发其他重要问题。

商家可能会告诉您,桌子的大小代表为该特定活动预订的数量,必须为此准备座位,而不是最大大小。因此,我们可以在 Table Bookings 表中拥有一个 Booked Size 列,并在 Tables 表中拥有一个 Maximum Size 列。(就像在在线购物应用程序中一样,客户可能有默认的帐单或送货地址,但每个订单都有特定的送货地址。)

您可能还意识到,我们缺少一个“活动客户预订”(或“活动客户聚会预订”)表,该表捕获该级别的数据,例如预计到达时间分配并最终确定数量。

数据建模至少部分是一种艺术形式,最有趣的一点是从业务中梳理出他们可能从未明确考虑过的细节、规则和关系。”

但是:“您可能会想到的几个问题:

a) 现在我们已经把所有这些数据都拆分了,它的用处是不是更少了?“关系数据库”的一个关键方面是它们非常擅长根据共同的价值将所有这些事实重新组合在一起。(您可能听说过人们使用术语“外键”。)这可能会让不太懂数据的用户感到困惑,但所有这些连接都可以隐藏在“视图”后面,它看起来很像表,但隐藏了 SQL 连接语言。

b) 这不会减慢速度吗?在捕获数据的系统中,3NF 实际上可以在添加、更改或删除数据时加快速度,因为您只需要在一行中进行更改。读取数据时,好的数据库连接速度非常快。

但对于高速仪表板或分析应用程序,我们有时会将数据折叠回“打破”规则的表中,以便我们可以更快地查询它们 - 这称为“反范式化”。当你这样做时,你最好了解你所违反的规则。这样做时,您确实会牺牲灵活性并重新引入重复。

c) 这些多字段键不是变得很复杂吗?是的,尤其是在捕获混乱的事情时,例如将共享姓名和地址的父子分开,或者处理诸如客户、日期、时间、产品、产品颜色都可能需要唯一主键的订单之类的事情。连接具有大量关键字段的表可能会更慢。

这就是为什么许多系统都有客户编号或订单号等业务主键的原因。而且,在幕后,数据库实现者有时会为几乎所有内容创建单列“代理”键。这很好,并且可以提供一定的灵活性 - 我们只需要关注“真正的关键”可能是什么,并确保不会将两个不同的东西挤到一张表中。

d) 事情不是一直在变化吗——比如人们的地址或产品价格?绝对如此——这意味着我们经常必须将时间因素带入我们的数据和主键中。有时前端系统需要这一点——例如当天的产品价格。有时,随着事物的缓慢变化,它会在分析阶段添加或暗示。

好了,我看到咖啡已经喝完了,恐怕要了解更多细节,您需要请我出去小酌一杯了……”

0
相关文章