AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 36324
Accepted
J86
J86
Asked: 2013-03-10 16:52:51 +0800 CST2013-03-10 16:52:51 +0800 CST 2013-03-10 16:52:51 +0800 CST

简单的场景需要从非标准化数据到 3NF - 请查看

  • 772

注意:问题已更新。查看编辑修订以查看原始问题。

情景。目前,一家动物慈善机构通过电子表格跟踪其机构的成本,如下所示:

[已删除损坏的图片链接]

1NF:

上表已经在 1NF 中,因为它遵守 1NF 的定义。

第一范式:每行和列的交集包含一个且仅一个值的关系。

在阅读了 Catcall 的回答后,我可以看到我搞砸了我的依赖关系。我最初所做的一切就像猫叫说的一样!添加了一个主键列,并对自己说“那里,解决了这个问题!”

所以很明显这是错误的。我现在已经更仔细地阅读了函数依赖,在我拥有的这本书中,它将它们定义为:

功能依赖:描述关系中属性之间的关系。例如,如果 A 和 B 是关系 R 的属性,并且 B 在功能上依赖于 A(由 A --> B 表示),如果 A 的每个值都与 B 的一个值相关联,则存在功能依赖。

牢记上述定义,并检查我现在扩展的(更多数据)示例表,我可以看到 PetHouse Ltd 并不总是与 Dog food 相关联,这打破了关于 A 与 EXACTLY one 相关联的定义部分B 的价值。

所以我想实际上我在识别我的功能依赖项时被困在这里。在这里,我有点不知所措,因为我从未使用过由三个不同列组成的复合键,但无论如何我都会继续前进,看看我能到达哪里。

Catcall 建议使用 3 列 [ Name, BoughtFrom, TimeBought ] 作为数据标识符(即由 3 列组成的表的复合键),这是有道理的,因为这将唯一标识表中的每一行数据。所以关系的符号变为:

IncuredCosts (名称, BoughtFrom , TimeBought , 成本)

我拥有的这本书也有一个有趣的部分,关于我们需要进行规范化的函数依赖。它指出我们所追求的功能依赖必须具有以下特征:

  • 左侧(行列式)的属性与函数依赖右侧的属性之间存在一对一的关系。(注意,相反方向的关系可以是一对一或一对多的关系。)
  • 他们一直持有。
  • 行列式具有维持与右侧属性的依赖关系所需的最少属性。换句话说,依赖关系左侧和右侧的属性之间必须存在完整的功能依赖关系。

我相信上述所有特征都适用于这种功能依赖:

(名称、BoughtFrom、TimeBought)-> 成本

现在,传递依赖,在书中(可能像 Catcall 所说的那样是错误的)被定义为:

传递依赖:一个条件,其中 A、B 和 C 是关系的属性,如果 A --> B 和 B --> C,则称 C 通过 B 传递依赖于 A(前提是 A 在功能上不是取决于 B 或 C)。

我认为我之前定义的关系没有任何传递依赖关系是否正确?但是话又说回来,如果是这样的话,那就意味着我已经达到了 3NF!显然,3NF 的主要步骤是将传递依赖关系移除到它们自己的关系中。

我真的达到了3NF吗?

顺便谢谢你。通过这篇文章我学到了很多东西。

database-design normalization
  • 3 3 个回答
  • 3406 Views

3 个回答

  • Voted
  1. Best Answer
    Mike Sherrill 'Cat Recall'
    2013-03-10T17:18:33+08:002013-03-10T17:18:33+08:00

    是的,它在 1NF 中。

    您不能通过在表格末尾挂一个数字并说“那里。我有一个主键”来回避确定所有候选键的艰巨工作。该表的一个自然候选键是{Name, Buy from, Date purchase}。考虑使用“购买时间”而不是“购买日期”。

    您对 2NF 的定义是错误的。代替

    第二范式:处于第一范式的关系,并且每个非主键属性在功能上都完全依赖于主键。

    你需要更多这样的东西。

    第二范式:处于第一范式的关系,每个非主属性在功能上完全依赖于每个候选键。

    术语非主属性并不完全意味着非主键属性的含义。

    您对 3NF 的定义是错误的,并且与您对 2NF 的定义错误的原因相同。

    而不是这个

    第三范式:处于第一范式和第二范式的关系,其中没有非主键属性可传递地依赖于主键。

    你需要更接近这个的东西。

    第三范式:处于第二范式的关系,其中每个非主属性都非传递地依赖于每个候选键。(没有一个很好的方法可以用一句话表达所有这些否定。)

    • 3
  2. Chris Saxon
    2013-03-11T02:50:02+08:002013-03-11T02:50:02+08:00

    确定您的表是否在 3NF 中的关键是传递依赖关系。要弄清楚你是否有这些,最好的问题是:

    如果我更改 x 列中的值,这是否意味着我也必须更改 y 列中的值?

    对于所有非主列。如果答案是肯定的,那么您不在 3NF 中。

    在这种情况下,您必须对name和bought_from列回答“是”。如果第三行是狗粮而不是汽油,那也意味着您必须换成bought_from英国汽油以外的人。

    要将其纳入 3NF,您需要一个单独的products表,其中列出了产品名称和供应商。然后,您将拥有一个外键 fromincurred_costs到这个新表的主键。

    • 1
  3. Chris Travers
    2013-03-10T18:39:22+08:002013-03-10T18:39:22+08:00

    首先,在我看来,您正在建立一个会计数据库。我只是建议您重新考虑或查看现有的开源数据库(例如,我维护 LedgerSMB)。

    其次,关于规范化,您需要额外的表格。你应该把你买的东西和你从谁买的东西分开到其他表中,然后有一个表,或多或少地记录你在这里的信息,但带有其他表的键,作为一个极简的解决方案。所以像(对不起这里的 PostgreSQL 主义):

    CREATE TABLE vendor (
       id serial not null unique, 
       company_name text primary key,
       vat_number text unique,
       ...
    );
    CREATE TABLE things_to_purchase (
       id serial not null unique,
       label text primary key,
       ....
    );
    CREATE TABLE invoice (
       vendor_id int not null references vendor(id),
       what_purchased int not null references things_to_purchase(id),
       when_purchased date not null,
       expense numeric not null
    );
    
    • 0

相关问题

  • 存储计算值或根据要求重新计算它们更好吗?[复制]

  • 存储与计算聚合值

  • 在数据仓库中实现多对多关系有哪些方法?

  • 高级规范化形式是否总是符合低级规范化形式的标准?

  • 标准化练习资源

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    授予用户对所有表的访问权限

    • 5 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve