首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >代理密钥与自然密钥/业务密钥

代理密钥与自然密钥/业务密钥
EN

Stack Overflow用户
提问于 2008-09-15 13:55:45
回答 19查看 75.9K关注 0票数 189

我们又来了,老调重弹...

我们是更好地将业务键作为主键,还是更愿意使用对业务键字段具有唯一约束的代理id (即SQL Server标识)?

请提供例子或证据来支持你的理论。

EN

回答 19

Stack Overflow用户

回答已采纳

发布于 2008-09-15 14:48:16

两者都有。把你的蛋糕吃了吧。

记住,主键没有什么特别之处,只是它被贴上了这样的标签。它只不过是一个非空的唯一约束,一个表可以有多个约束。

如果您使用代理键,您仍然需要一个业务键,以确保业务规则的唯一性。

票数 108
EN

Stack Overflow用户

发布于 2008-09-15 14:06:23

以下是使用代理键的几个原因:

  1. Stability:由于业务或自然需要而更改键将对相关表产生负面影响。代理键很少需要更改,因为没有绑定到value.
  2. Convention:的意义允许您具有标准化的主键列命名约定,而不必考虑如何为PKs.
  3. Speed:连接具有各种名称的表。根据PK值和类型,整数的代理键可能更小,索引和搜索速度更快。
票数 131
EN

Stack Overflow用户

发布于 2009-02-12 14:54:36

似乎还没有人说过支持非代理(我不太愿意说“自然”)键。所以开始吧..。

代理键的一个缺点是它们是无意义的()(有些人认为这是一个优点,但是……)。这有时会迫使您将更多的表连接到查询中,而不是真正需要的。比较:

代码语言:javascript
复制
select sum(t.hours)
from timesheets t
where t.dept_code = 'HR'
and t.status = 'VALID'
and t.project_code = 'MYPROJECT'
and t.task = 'BUILD';

反对:

代码语言:javascript
复制
select sum(t.hours)
from timesheets t
     join departents d on d.dept_id = t.dept_id
     join timesheet_statuses s on s.status_id = t.status_id
     join projects p on p.project_id = t.project_id
     join tasks k on k.task_id = t.task_id
where d.dept_code = 'HR'
and s.status = 'VALID'
and p.project_code = 'MYPROJECT'
and k.task_code = 'BUILD';

除非有人真的认为以下是一个好主意?

代码语言:javascript
复制
select sum(t.hours)
from timesheets t
where t.dept_id = 34394
and t.status_id = 89    
and t.project_id = 1253
and t.task_id = 77;

“但是”有人会说,“当MYPROJECT或VALID或HR的代码更改时会发生什么?”对于这个问题,我的回答是:“为什么需要来更改它?”从某种意义上说,这些不是“自然”键,因为一些外部机构将立法,从今以后“有效”应该被重新编码为“好”。只有一小部分“自然”键真正属于这一类- SSN和Zip代码就是常见的例子。我肯定会对Person、Address这样的表使用无意义的数字键-但不会对everything使用,因为出于某种原因,这里的大多数人似乎都提倡使用它。

另请参阅:my answer to another question

票数 78
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63090

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档