代理与自然键:性能差异的硬性数字?

2023-12-29

代理键和自然键之间存在着一场健康的争论:

所以帖子 1 https://stackoverflow.com/questions/1207983/in-general-should-every-table-in-a-database-have-an-identity-field-to-use-as-a-p

所以帖子2 https://stackoverflow.com/questions/63090/surrogate-vs-natural-business-keys

我的观点似乎与大多数人(微弱多数)一致,即您应该使用代理键,除非自然键完全明显并且保证不会更改。然后您应该强制自然键的唯一性。这意味着几乎所有时候都需要代理键。

两种方法的示例,从 Company 表开始:

1:代理键:表有一个 ID 字段,它是 PK(和身份)。州要求公司名称是唯一的,因此存在唯一约束。

2:自然键:表使用CompanyName和State作为PK——既满足PK又满足唯一性。

假设 Company PK 用于其他 10 个表。我的假设(没有数字支持)是代理键方法在这里会快得多。

我见过的关于自然键的唯一令人信服的论据是对于使用两个外键作为自然键的多对多表。我认为在这种情况下这是有道理的。但如果您需要重构,您可能会遇到麻烦;我认为这超出了本文的范围。

有谁看过比较的文章性能差异在一组使用的表上代理键 vs.使用同一组表自然键?环顾 SO 和 Google 并没有产生任何有价值的东西,只是大量的理论构建。


重要更新: 我已经开始构建一个一组测试表回答这个问题。它看起来像这样:

  • PartNatural - 使用的零件表 作为 PK 的唯一 PartNumber
  • PartSurrogate - 零件表 使用ID(int,identity)作为PK并且 PartNumber 上有唯一索引
  • 植物 - ID(int,identity)作为 PK
  • 工程师-ID(int,identity)作为PK

每个零件都连接到一个工厂,并且工厂中零件的每个实例都连接到一个工程师。如果有人对此测试平台有疑问,现在就是时候了。


两者都用!自然键可以防止数据库损坏(不一致可能是一个更好的词)。当“正确的”自然键(为了消除重复行)由于长度或涉及的列数而表现不佳时,出于性能目的,也可以添加代理键以用作其他表中的外键,而不是自然键...但是自然键应该保留作为备用键或唯一索引,以防止数据损坏并强制数据库一致性...

大部分的欢呼(在关于这个问题的“辩论”中)可能是由于一个错误的假设 - 你必须使用首要的关键用于其他表中的联接和外键。这是错误的。你可以使用任何key作为其他表中外键的目标。它可以是主键、备用键或任何唯一索引或唯一约束,只要它在目标关系(表)中是唯一的。至于连接,你可以使用anything对于连接条件来说,它甚至不必是键、索引,甚至不必是唯一的! (尽管如果它不是唯一的,您将在它创建的笛卡尔积中获得多行)。您甚至可以使用非特定条件(例如 >、

事实上,您可以使用任何计算结果为布尔值的有效 SQL 表达式来创建联接。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

代理与自然键:性能差异的硬性数字? 的相关文章

  • 长 IN 子句是代码异味吗?

    简单的问题 想知道长 IN 子句是否有代码味道 我真的不知道如何证明它的合理性 除了我认为的味道之外 我无法解释为什么它有味道 select name code capital population flower bird from us
  • 检查 u 键是否被按下 Swift Cocoa [重复]

    这个问题在这里已经有答案了 我正在尝试检测是否U键是否被按下 如果是的话应该print BUT BUT 但我不确定如何检查不同的按键 因为按键的文档非常糟糕 我找到了带有键码的答案 但它们仅适用于 QWERTY 键盘 视图控制器 swift
  • SQLite 性能基准 - 为什么 :memory: 这么慢...只有磁盘速度的 1.5 倍?

    为什么 sqlite 中的 memory 这么慢 我一直在尝试查看使用内存中的 sqlite 与基于磁盘的 sqlite 是否可以获得任何性能改进 基本上我想用启动时间和内存来换取非常快速的查询not在应用程序过程中击中磁盘 然而 以下基准
  • Rails 5:迭代的数据库设计

    我目前有一个包含用户 餐食和订单表的网站 Users表保存用户信息 餐食表包含餐食名称 描述 img url 我目前正在使用迭代来显示餐食 span class mealname span p p p p div class qty INP
  • 在实时计算机上更新(或替换)整个数据库表的最佳方法是什么?

    我每周都会收到一个数据源 我将对其进行解析并放入数据库中 数据每周不会有太大变化 但我应该定期更新数据库 除了每周更新外 数据是静态的 目前重建整个数据库不是问题 但最终该数据库将上线 人们可以在我重建数据库时查询该数据库 数据量并不小 几
  • 关于ORA 21000

    我正在与 ORA 21000 作斗争 上面写着ORA 21000 raise application error 的错误号参数 3739 超出范围 此错误间歇性出现 我不知道为什么会发生这种情况 早些时候这工作得很好 但是从 Solaris
  • 在 MySQL 中对连续值进行分组并向这些组添加 id

    我有一个简单的表 我需要确定四行的组 这些组不是连续的 但每行的每一行的值都有 1 例如 language id C 16 C 17 Java 18 Python 19 HTML 65 JavaScript 66 PHP 67 Perl 6
  • cdb - 大文件(数百 GB)的常量键值存储

    我需要一个类似于 cdb 常量数据库 的工具 它允许我在索引文件中存储大量数据 数百 GB 范围内 CDB 是理想的候选者 但它有 2 GB 的文件大小限制 因此不适合 我正在寻找的功能是支持二进制键和值的持久键值存储 创建后数据库是只读的
  • 环回:原子读取和更新

    有没有办法在环回中实现类似的东西 LOCK READ INCREMENT UNLOCK 我想将计数器保留为数据库值 每个键都是一个计数器 或一个设置 并且它们不应该同时访问我的多个请求 此外 这也应该适用于本地请求 无 RemoteHook
  • 在cakephp 3中动态更改数据库连接

    我正在尝试更改中使用的数据库连接蛋糕php 3在飞行中 我找到的这个问题的每个答案都指的是蛋糕PHP 2 These https stackoverflow com questions 27655613 multiple databases
  • 时间序列数据的键值存储?

    我一直在使用 SQL Server 存储数十万个对象的历史时间序列数据 每天观察大约 100 次 我发现查询 给我时间 t1 和时间 t2 之间对象 XYZ 的所有值 太慢 对于我的需要 慢超过一秒 我按时间戳和对象 ID 建立索引 我考虑
  • DB2连接授权失败原因:Java不支持安全机制

    我正在尝试使用 DB2JDBC Type4 驱动程序配置 DB2 连接 但我收到这个错误 线程 main 中的异常 com ibm db2 jcc am SqlInvalidAuthorizationSpecException jcc t4
  • Elasticsearch 聚合过滤器

    因为我在谷歌上找不到任何东西 是否可以在elasticsearch中过滤聚合 我正在考虑这样的事情 获取 SOME object X gt 100 的所有对象 提前致谢 编辑 样本数据 我有以下文档结构 docKey 1 value 2 d
  • PostgreSQL 中字符串列类型的索引数组

    是否可以在类型为的列上创建索引文本数组 尝试使用GIN索引 但查询似乎没有使用这些索引 Example CREATE TABLE users name VARCHAR 100 groups TEXT Query SELECT name FR
  • 什么时候不应该使用 Cassandra? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 相关话题已经有很多讨论了卡桑德拉 http cassandra apache org lately Twitter Digg Facebook
  • 使用 Greasemonkey 时存储数据

    使用 Greasemonkey 时是否有存储大量数据的好方法GM setValue只是没有削减它 那么这里有一些选项 设置服务器来保存数据 对于用户 并使用 xhr 来 创建 编辑 删除数据 谷歌应用程序 发动机 GAE http code
  • 通过 Matlab 访问 Physionet 的 ptbdb 中的数据库

    我首先设置系统 old path which rdsamp if isempty old path rmpath old path 1 end 8 end wfdb url http physionet org physiotools ma
  • 数据库分片和 Rails

    在 Rails 中处理分片数据库的最佳方法是什么 分片应该在应用层 活动记录层 数据库驱动层 代理层还是其他层处理 各自的优点和缺点是什么 FiveRuns 有一个名为的 gem数据结构 https github com bpot data
  • Mysql 中 UNION 子句的替代方案

    我有两张桌子 表 a 表 b table a ID 1 2 3 4 5 7 table b ID 2 3 4 5 6 我必须得到这样的输出而无需UNION命令 ID 1 2 3 4 5 6 7 注意 我有一个联合解决方案 select fr
  • 如何在列上创建外键,该列的每条记录都可能引用多个表之一中的列?

    我正在创建一个社交网络 它有新闻 照片等多个实体 可以有评论 由于所有评论都具有相同的列并且行为方式相同 唯一的区别是它们的类型 新闻 照片或将来添加的其他内容 我决定为所有评论创建一个表 其中的列名为type 它工作得很好 直到我决定将外

随机推荐

  • 如何将扩展编译成sqlite?

    我想将扩展编译到 sqlite 中以便在运行时加载 我使用的文件扩展名为 functions c 来自https www sqlite org contrib https www sqlite org contrib 我已经能够编译成可加载
  • 在 Rails 中使用域逻辑回调的优点和缺点

    您认为使用领域逻辑回调的优点和缺点是什么 我是在 Rails 和 或 Ruby 项目的背景下谈论的 为了开始讨论 我想提一下来自关于回调的 Mongoid 页面 http mongoid org en mongoid docs callba
  • 从命令行在 Firefox 上安装 WebExtensions

    我找到了问题如何在脚本中从命令行安装 Firefox 插件 https askubuntu com questions 73474 how to install firefox addon from command line in scri
  • 如何在没有 UI 的情况下启动 Activity?

    是否可以在没有 UI 的情况下从主函数启动 Activity 即是否有一种方法可以围绕另一个活动创建一种 包装器 即通过启动主要活动 它会自动将您带到另一个活动 如果这是不可能的 是否有办法从堆栈中删除主要活动 以便单击后退按钮不会将您带到
  • Objective C 数组元素都以相同的值结束

    首先 如果这是一个相当基本的问题 我深表歉意 但是我是 Objective C 的新手 并且在我所有的搜索中都无法找到我的问题的答案 尽管这很可能是因为我是新手而不是新手 在寻找答案时相当使用正确的术语 我有一个简单的循环 在其中我用一些自
  • nltk 没有将 $NLTK_DATA 添加到搜索路径?

    在linux下 我设置了环境变量 NLTK DATA home user data nltk 并且爆炸测试按预期工作 gt gt gt from nltk corpus import brown gt gt gt brown words T
  • NetSuite Restlet写入性能较差

    编辑 我已经编辑了实际数字并用伪咒语替换了它们 因为我被告知共享性能数据违反了 Netsuite 的 TOS 我正在使用 Restlet 将我们的会计系统与 NetSuite 集成 总体来说 除了性能方面的明显例外之外 它运行得非常好 从性
  • 使用 Java 流打印列表项

    我可以使用类似的东西 forEach System out print 打印我的列表项 但如果我在打印之前还有其他操作要做 我就不能像这样使用它 mylist replaceAll s gt s toUpperCase forEach Sy
  • 如何将多个分区的 .gzip 文件读入 Spark Dataframe?

    我有以下分区数据文件夹 my folder part 0000 gzip part 0001 gzip part 0002 gzip part 0003 gzip 我尝试使用以下方法将这些数据读入数据帧 gt gt gt my df spa
  • 启动 Oozie 工作流程时出现问题

    我在启动 Oozie 工作流程时遇到问题 Config
  • 使用通用类库中的 Windows UWP Windows.Devices.SerialCommunication.SerialDevice

    我正在制作一个 Modbus 库 再次 这次它打算在 Windows 10 IoT Core 上运行 我遇到了一个有趣的问题 这段代码 string aqs SerialDevice GetDeviceSelector var dis aw
  • 假设的串联困境

    所以我正在为 PHP 开发一种简单的微语言 替代语法 它的语法大量借鉴了 JavaScript 和 CoffeeScript 包括一些我自己的概念 我在 PHP 中手工编写了解析器 未使用解析器生成器 将代码转换为 PHP 然后执行它 它更
  • Rmarkdown:如果列名具有用反引号定义的空格,则编写内联 dplyr 代码

    Problem 当我filter or select 具有空格的列名称 我通常在 dplyr 中使用反引号定义该空格 示例数据 r setup include FALSE knitr opts chunk set echo TRUE lib
  • Inno Setup:使用注册表部分中自定义向导页面的数据

    我想知道如何使用自定义向导页面的用户输入值 我有一个自定义页面 用户可以在其中键入 ODBC 连接数据 这是这部分的代码 ServerDataPage CreateInputQueryPage AskAuthPage ID SQL Serv
  • Django mod_wsgi apache

    当我尝试访问我的 Django 网站时http www satoshi example com mysite http www satoshi example com mysite我得到一个503 Service Temporary Una
  • 将数据从 NSOperation 传递到下一个 NSOperation

    是否可以将数据从 NSOperation 传递到依赖链以供下一个 NSOperation 使用 Thanks Chris 是的 目前的NSOperation可以通过以下方式访问其依赖项dependencies method NSArray
  • 添加 root 密码,无法访问 phpmyadmin

    使用 phpmyadmin 我将用户 root 的密码 本地主机条目和 127 0 0 1 条目 从空白更改为 password 然后我被锁定在 phpmyadmin 之外 收到 1130 错误 主机 localhost 不允许连接到此 M
  • 在页面加载时停止加载详细网格

    如何阻止 DetailGrid 在页面加载时不加载 因为我在主网格中有按钮来加载详细网格 以下是详细网格的代码 jQuery ready function jQuery list10 d jqGrid height 100 url JQSa
  • 我可以将另一个程序的窗口移动到焦点前面吗?

    我正在使用其 API 与第三方应用程序进行交互 并且希望当用户执行特定操作时将其移至焦点前面 以便它位于所有其他打开的窗口之上 虽然我可以轻松地在层次结构中上下移动应用程序 但似乎没有办法与其他窗口交互 是否可以用Java将另一个程序的窗口
  • 代理与自然键:性能差异的硬性数字?

    代理键和自然键之间存在着一场健康的争论 所以帖子 1 https stackoverflow com questions 1207983 in general should every table in a database have an