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 / 问题 / 117679
Accepted
Bohemian
Bohemian
Asked: 2015-10-12 07:26:40 +0800 CST2015-10-12 07:26:40 +0800 CST 2015-10-12 07:26:40 +0800 CST

如果一个带有代理键的表有一个已知的列具有唯一的非空值(例如 SSN),它是否违反 3NF?

  • 772

据我了解,第三范式(3NF)基本上意味着应该只有一把钥匙。

如果一个带有自动递增id列的表也有一个已知唯一且不为空的列,例如社会保险号,则该其他列可以用作键。

忽略实际/业务问题(例如,将 SSN 作为密钥/FK 传递时的安全/隐私风险),从严格的模式设计方面来看,这样的表是否不在 3NF 中,因为实际上有 2 个密钥?

答案是否会根据另一列是否有唯一键而有所不同?如果是这样,为什么?

database-design relational-theory
  • 3 3 个回答
  • 1369 Views

3 个回答

  • Voted
  1. nvogel
    2015-10-13T09:10:20+08:002015-10-13T09:10:20+08:00

    如果 R 的每个非主属性都非传递地依赖于 R 的每个候选键,则关系 R 处于第三范式

    EFCodd,1971,数据库关系模型的进一步规范化

    在关系的定义中隐含了一个关系必须至少有一个键。3NF 或任何其他范式都没有要求一个关系应该只有一个键。

    不幸的是,关于数据库设计和规范化的书籍有大量仅具有单个键的关系示例,而具有多个键的示例则更少。这让我觉得很奇怪,因为现在多个键似乎是非常普遍的做法。非学术文献中缺乏实际例子似乎是导致人们混淆键在数据库设计中的作用的原因之一。造成混淆的另一个原因是流行的助记符“nothing but the key”。该短语通常归因于 Bill Kent,但它并不是 3NF 的准确定义。

    • 8
  2. Best Answer
    Todd Everett
    2015-10-23T12:04:21+08:002015-10-23T12:04:21+08:00

    据我了解,第三范式(3NF)基本上意味着应该只有一把钥匙。

    No. 2NF、3NF 和 Boyce Codd Normal Form (BCNF) 处理函数依赖。2NF 中的表意味着不存在部分键依赖关系,其中非键列依赖于多列键的某个适当子集。我们例子中的表已经是 2NF 了,因为每个候选键都是一个列。3NF 中的表意味着每个非键列在功能上也不依赖于其他一些非键列,因此创建了传递依赖. 有一个或一百个候选键并不重要。实际上它是 BCNF,而不是 3NF,它是关于功能依赖的“最终”范式。这是因为表可以在 3NF 中但不在 BCNF 中,因为可能有多个重叠的候选键。因此,当我们使用术语3NF来表示关于函数依赖性的“完全规范化”时,我们真正的意思是 BCNF。

    如果一个带有自动递增 id 列的表也有一个已知唯一且不为空的列,例如社会安全号码,则该其他列可以用作键。

    如果我们要确保存储在数据库中的数据与我们在现实世界中确定的规则保持一致,不仅可以,而且必须是!

    忽略实际/业务问题(例如,将 SSN 作为密钥/FK 传递时的安全/隐私风险),从严格的模式设计方面来看,这样的表是否不在 3NF 中,因为实际上有 2 个密钥?

    如上所述,该表是否符合 3NF(或更重要的是 BCNF)与其包含多少候选键正交。

    答案是否会根据另一列是否有唯一键而有所不同?如果是这样,为什么?

    不,仅仅因为确定表是否在 3NF 中与它有多少个候选键无关。相反,它与确保所有非键列在功能上完全依赖于这些候选键有关。

    但这确实提出了一个有趣的观点。请注意,在 DBMS 中定义为约束的唯一键与概念业务模型中定义为业务规则的唯一标识符不同。也许在我们的世界中,我们总是知道这个人的 SSN,因此它作为一个人的候选键,也许我们还在我们称为Person Id的逻辑模式中引入了一个代理键。我们的商业模式包括规定 SSN 是我们这个世界上一个人的唯一标识符的规则。这意味着功能依赖此身份属性上的所有描述性属性。这条规则不会因为我们忘记或选择不通知 DBMS 而改变。这正是声明约束至关重要的原因——这样 DBMS 才能确保存储的数据符合业务模型的规则!如果我们没有在 SSN 上创建唯一约束,我们现在可能会无意中为具有相同 SSN 的同一个人创建多行;每一行都有不同的 Person Id!

    Fabian Pascal 的Practical Database Foundation Series和 Chris Date 的Database Design and Relational Theory是关于这些主题的优秀入门书,这个答案就是从中得出的。虽然 Fabian 的每篇论文都是必读的,但论文 #1(明确定义了概念、逻辑和物理层面之间的区别)和论文 #4(明确定义了各种键)专门解决了这个问题。同样,Chris 的整本书都是必读的,而第二部分是专门讨论函数依赖性规范化的部分。

    • 5
  3. Solomon Rutzky
    2015-10-23T11:48:02+08:002015-10-23T11:48:02+08:00

    由于问题是基于对规则的解释,我们应该首先查看链接信息,即(强调我的):

    1. 表中的所有属性仅由该表的候选键决定,而不是由任何非素数属性决定。

    我认为混淆是误解术语“候选键”的结果。一张表中可以有多个候选键。这就是为什么我们要在这个组中进一步指定修饰词:主要和备用。如果表可以有一个,而且只有一个,键,那么术语“主”键会产生误导,而应该被称为其他名称(可能是“父”或“来源”或“标识”等)。但是“主要”意味着可以有“次要”键,这些被称为“备用”键。

    备用键通过唯一约束或唯一索引在物理模型中指示。还应该注意的是,两种类型的候选键(主键和备用键)都可以被外键引用(即使没有很好的理由通常不会/不应该做这样的事情!)。

    答案是否会根据另一列是否有唯一键而有所不同?如果是这样,为什么?

    不,因为这是物理与逻辑建模的问题。您可以拥有一个包含IDENTITY字段但尚未定义主键的表。表及其数据可以很容易地处于 3NF 中,即使物理模型不强制执行。这种区别类似于是否定义了外键。您肯定可以 JOIN 表,并且没有孤立记录,无论是否定义了任何 PK/FK。没有这些结构,数据可以 100% 正确。但是定义 PK 和 FK 是参照完整性(逻辑)和声明性参照完整性(物理)之间的区别。在物理模型中加入约束只是有助于执行逻辑模型的规则。


    关于 SSN(对于那些不熟悉该首字母缩略词的人来说是“社会安全号码”),它是一个备用键,并且有一个唯一的索引/约束:

    我建议不要将 SSN 视为备用密钥并在其上放置唯一约束或索引,即使这样做很常见(SSN 通常被认为是“自然”密钥——现实世界中存在的密钥) . 主要有两个原因:

    1. 准确性:大多数时候,这些值是由填写表格的人输入系统的,无论是纸质表格还是在线表格。人们在输入数据时总是会犯错误,尤其是如果源是纸质表格,而该表格是由某人阅读别人草率的笔迹(例如我的,几乎无法辨认)输入的。

      即使数据来自另一个系统,你能确定源系统验证了信息吗?你能确定他们的数据导出没有错误吗?如果您的数据导入出现错误怎么办?

    2. 唯一性:即使主要的社会保障管理局从未颁发过重复的 ID,这并不意味着没有发生重复。除了身份盗用问题之外,我记得几年前曾听人说过,他曾在美国税务局担任 DBA(我相信),并且必须处理社会保障福利,他们如何处理“问题”将死者的 SSN 重新分配给尚存的配偶(通常是寡妇)的旧做法,以便尚存的配偶更容易继续领取福利金。我敢肯定这种做法不久前就结束了,但“重复”数据仍在系统中。

    • 3

相关问题

  • MySQL VARCHAR 和 TEXT 数据类型有什么区别?

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

  • 存储与计算聚合值

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

  • 如何构建模型以正确有效地表示关系数据库上的树状数据?

Sidebar

Stats

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

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

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

    • 3 个回答
  • Marko Smith

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

    • 3 个回答
  • Marko Smith

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

    • 4 个回答
  • 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
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • 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
    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