sql - 我们是否应该将代理键与自然键(唯一索引均值)结合起来以提高可读性并易于查询选择?

标签 sql sql-server database primary-key composite-key

编辑:目前我将保持问题未决。得到一个非常粗略的答案。

简单来说,这是一个架构

enter image description here

enter image description here

问这个问题是因为来自这个主题https://www.sisense.com/blog/when-and-how-to-use-surrogate-keys/

Combining Natural and Surrogate Keys Certain business scenarios might require keeping the natural key intact as a means for users to interact with the database. In these cases …

If a natural key is recommended, use a surrogate key field as the primary key, and a natural key as a foreign key. While users may interact with the natural key, the database can still have surrogate keys outside of the users’ view, with no interruption to user experience.

If a natural key must be used without an additional surrogate key, be sure to combine it with a surrogate key element. In our financial database example, Expense Reports (ER-123) have a natural key is used in conjunction with a surrogate sequential key. This format prevents many of the natural key side effects listed above.

我真的发现也许可以解决我的问题。因为害怕代理键。但 XPO 和 ORM 提供商支持代理键 (100%)。与复合键不同。许多文章将其描述为新数据库设计中的一个糟糕之处。 Surrogate Key vs Natural Key for EF Surrogate vs. natural/business keys

还有很多相关文章。这里不是这种情况。我正在谈论组合或使用代理键并添加自然键(仅作为索引或唯一索引而不是 PK) 现在回到上面的架构和上面讨论将两者结合起来的主题。我有一个具有代理键 Oid 的分支,所有表都具有 Oid 作为代理键。我还有自然键,例如(BranchID),

  1. 分支表有 (Oid[代理], BranchID[自然键 - 唯一索引而非 PK]
  2. InvTransHed 将 (Oid[Surrogate]、itd_brn、itd_type、ith_num) 作为自然键(我的意思是唯一索引)
  3. InvTransDet 有(Oid[代理]、itd_brm、itd_typ、itd_num、itd_lne 作为自然键 [唯一索引])

我实际上所做的是将所有代理键 Oid 与其外键侧链接起来。例如: Branch.Oid 与 InvTransHed.BranchSKey 链接 [Skey = 代理键]

为什么我需要将代理键与自然键(作为唯一索引)结合起来?

  1. 使用 JOIN 轻松创建报告(直接使用 InvTransDet 进行分支,无需移至 InvTransHed)。
  2. 技术支持的可读性。轻松进行任何连接,无需关心代理键。或链接到父表直到达到我们的需要。
  3. 易于理解的 ORM 提供程序(肯定 100% 友好)

这是一个让我大吃一惊的问题:

  1. 我应该仅将代理键与其另一侧外键链接起来吗?或者我必须将自然索引也链接到它们的自然键。 Branch.BranchID => InvTransHed.ith_brn
  2. 关于命名对方FK。 Branch.Oid 代理与 InvTransHed.BranchSkey 链接。为了可读性,命名是否重要?
  3. 请指导我(标题 = 问题)。

最佳答案

像 PK 和 FK 这样的约束是我们记录和实现数据库引用完整性的主要机制。

We can't rely on documentation and data schema naming conventions alone to explain to developers and users how to interpret the data. The whole point around using an RDBM is to maintain referential integrity. Referential and any check constraints form the basis of "truth" about the rules that must be adhered to when inserting data into the database.

您正确地指出,您希望强制FK自然代理键组合的唯一性,因此这是主要是一个约束

如果约束的存在不成问题,那么我们只需要考虑索引

  • Unique Constraint vs Unique Index

    唯一约束没有必要与唯一索引配对,但是对于开发人员的发现来说,它只是更多文档或者如果您也将其定义为索引,则至少更易于发现。

当或如果性能成为问题时,您可能会更改索引的唯一性或将其完全删除,但是您总是希望在这种情况下保持唯一约束,以确保索引的完整性数据。


虽然不是必需的,但一致的命名约定有助于提高数据模式的可读性并解释结构的意图,但一致性是关键,首先当你违反约定时,读者现在必须怀疑或再次猜测之前的所有假设。

For this reason, if conventions might be questioned, existence of constraints will always provide a definitive answer.

您使用的实际命名约定将成为设计者的个人偏好。我使用 Id 作为 PK,使用 {tablename}Id 作为 FK。当链接不明确时,例如当一个表具有其自身的 FK 或同一表的多个 FK 时,我会在该列前添加描述该链接的名词动词关系:CreatedBy_UserIdModifiedBy_UserId

我认为这种约定适合于可读且自然的 SQL 和 C# 语法。

SELECT ID, Description, Modified, ModifiedBy.Name
FROM Product
INNER JOIN User [ModifiedBy] ON Product.ModifiedBy_UserId = ModifiedBy.Id

作为惯例,我知道 PK始终 Id,因此无论在何处使用它,您都可以假设它是主体> 关系结束。

关于sql - 我们是否应该将代理键与自然键(唯一索引均值)结合起来以提高可读性并易于查询选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66280920/

相关文章:

php - 使用 sqlsrv 切换数据库的正确方法是什么?

node.js - 有没有办法在维护数据的同时更改 mongoDB 结构(从嵌套/嵌入文档到对象引用列表)?

sql - 使用 having 子句查找记录

php - 从 mysql/php 中的用户 ID 检索消息

c# - 手动增加数据库中的值

sql - 动态 SQL 结果 INTO 临时表

sql - 为什么SqlServer优化器对参数如此困惑?

mysql - 如何计算rails 3中has_many关联之间平均值的较大值

sql - Crystal 报表 - 分组依据

MYSQL 左连接不正确的结果