选择好的主键,候选键和使用它们的外键是一项非常重要的数据库设计任务 - 与科学一样多的艺术。设计任务有非常具体的设计标准。
有什么标准?
答案 0 :(得分:18)
主键是唯一标识数据行/记录的东西。它也可以是多列,称为复合。
因为主键通常用于外部引用,所以它应该尽可能稳定。数据库中的所有数据都是可变的,前提是某人正在使用具有适当权限的帐户进行连接。这就是数据库提供定义CASCADE ON DELETE和CASCADE ON UPDATE的能力的原因 - 无需禁用约束即可同步参照依赖项。
理想情况下,您需要一个自然键。自然键是唯一标识您正在建模的实体的现有数据。例如,美国州的缩写是一个很好的自然关键,因为缩写是一致的,每个人都知道它们:
US_STATE_PRIMARY_KEY US_STATE
--------------------------
AL Alabama
AK Alaska
AZ Arizona
AR Arkansas
CA California
不要太努力找到自然的钥匙。它们很少存在。美国国家名称不太可能改变,但这似乎是合理的。
实际上,主键通常是人为的(通常由数据库功能生成)。这些通常是数字或GUID,它们被认为是人为的,因为它们本身 - 没有任何东西可以将它们的价值与它们唯一识别的信息联系起来。销售收据总是有编号的,因为它没有任何关系,它也适用于审计 - 收据数量的差距引起了怀疑。为了演示任意编号是多少,这里是美国州表,但是使用主键列的整数,US_STATE_CODE:
US_STATE_PRIMARY_KEY US_STATE
--------------------------
100 Alabama
101 Alaska
102 Arizona
103 Arkansas
104 California
没有要求在一个值上启动值;一些商店将此作为一种安全措施来阻止SQL注入。该值是基于州名的字母顺序的顺序,但不能保证。但与自然键不同,如果状态名称发生更改 - 只需要更新一列。
理想情况下,一列将是主键,但是根据手头的数据做出决定 - 不要仅为了拥有单个列而组合列。如果你一起做鞋拔数据,可以使用一个字符轻松分离数据(尽管这样做的操作将无法利用索引)。
从性能的角度来看,整数是最好的,因为它们提供了一个合适的值范围,并且当您与五个或更多字符的VARCHAR进行比较时,使用的字节数很小。
答案 1 :(得分:15)
考虑主键的标准是:
答案 2 :(得分:8)
答案 3 :(得分:4)
主键是唯一标识实体的键。当您选择主键时,最佳选择几乎总是一个代理键,除了唯一识别它之外,它与该实体完全无关。
就是这样。据说罕见的边缘情况,主键可能是一个自然键,但我从未见过有效的键。
我们大多数人使用32位自动增量整数作为主键。另一个很好的选择(在某些情况下)是UUID。
答案 4 :(得分:4)
候选键是一组不可简化的唯一属性(不可简化意味着在不丢失唯一性属性的情况下,不能从键中删除任何属性)。
选择要实施的候选键时的其他标准是:简单,稳定,熟悉。
这三个标准是重要的考虑因素,但不一定是关键的基本属性。例如,强制执行经常更改的密钥可能是合乎需要的并且非常合理。例如:用户登录名必须是唯一的,但用户可以随意更改,只要它保持唯一。
主键是候选键。
答案 5 :(得分:3)
嘿。它再次开放。到此为止。
(1)选择好的候选键。
选择候选键与数据库设计者无关。 数据库设计者有责任确保所有这些 将由用户通知他的唯一性要求,将被强制执行。 因此,用户“选择”候选键是什么。
有两种情况可以让我想到放松这种明确的态度 有点位置。
一个是用户说某些属性类型为“视频”或“音频”(或 一些这样的)是独一无二的。实际执行可能是不可行的 那,设计师有责任指出这一点 用户(因为他也有责任指出'独特性' 音频和视频内容是一个非常值得商榷的主题 这些属性值的唯一性,即使系统可以强制执行, 仍然很有可能与用户没有相同的独特性 要)。
其次是图片如何被不同的可能性弄糊涂了 逻辑设计都解决了同样的问题。如果D1和D2都是 有效的设计解决了同样的问题,那么可能就是这样 用户施加的某个给定的唯一性规则可以使用强制执行 D1中的键,但不在D2中。从这个角度来看,“选择候选人 键“可以被解释为”选择特定的设计,使得a 给定唯一性规则可以使用密钥强制执行“。但事实并非如此 你提出的问题。
(2)选择好的主键。
不久前,Darwen提出了“单身有什么好理由”的问题 一个特定的候选人从其他人中选择为“主要”?“ 没有什么可以出来的,除了那个或许:“建议这个 特殊键是在引用时使用的首选键 这个relvar“。我怀疑他们没有找到令人信服的变化 他们早先的决定是“没有钥匙比任何其他钥匙更独特”。
但是,假设存在单一的有效理由 把一个特定的密钥称为“主要”,我想以下几点 考虑适用:
答案 6 :(得分:3)
你对欧文的回答: “我同意选择一个主键仅指定一个候选键作为外键引用的首选。但是,即使我们完全删除了”主键“这个名称,设计者仍然必须选择将哪个候选键传播到另一个关系中以供参考。如果用户使用不稳定的复合键识别出重度引用的关系,您是否打算暗示设计人员没有业务选择额外的简单,稳定的密钥?或者使用简单,稳定的密钥来引用关系?您的候选关键部分似乎意味着。 - bbadour 8小时前“
您最初的问题是关于'主键'。现在,您将焦点更改为键和外键。密钥是完整性约束,因此唯一的标准是最小的属性集必须在关系中唯一(唯一性和不可简化性)。如果我们将注意力转移到外键上,那么简单性,稳定性和熟悉度是从参考关系中的所有候选键中进行选择的标准。可能有更多候选键满足该标准或多或少相同的扩展。如果我们看一下熟悉度,一个候选密钥可能对一组用户非常熟悉,而不是另一个候选密钥更熟悉的另一个组。考虑数据库的不同视图或子模式。第二组用户应选择不同的候选密钥以供参考(作为外键)。如果你坚持使用“主键”,我们每个关系只有一个,那么我必须问一下什么使一个键比其他键更重要。 我认为不应该使用术语主键。至少在逻辑层面。此外,“外键”一词也没有很好地选择(外键不是键,而是引用)。
所以,我认为Erwin关于'主要'键的评论非常重要。或者至少这是我对他的意思的解释。
你同意吗? 如果是这样,您是否会将原始问题更改为“密钥的设计标准是什么?从可用的候选密钥中选择外键的标准是什么?”? 如果没有,为什么?
此致 卡洛斯
答案 7 :(得分:2)
主键是为特殊处理选择的候选键,因此首先我们必须查看候选键的属性。如果具有以下两个属性,则一组一列或多列是候选键:
唯一性:候选键必须唯一标识表中的每一行。没有表可能包含两个具有相同候选键值的行。
不可降低性:从候选键中删除任何列必须违反uniqness属性。换句话说,候选键中没有列的子集本身就是候选键。
如果不存在候选键,有时即使有候选键,也常常使用自动递增整数列创建代理键,或者使用其他技术组成代理键。这个代理键现在也是候选键。
在可用的候选键中进行选择并将其中一个指定为主键通常很有用。经常应用的第一个标准是简单性,表示具有最少列的候选键。然而,还有其他潜在的标准,比如熟悉,熟悉的值比非熟悉的值更有用,稳定性,稳定的键比易于改变的键更不麻烦。然而,这些标准在关系模型的范围之外是严格的,经常相互冲突,并且经常被用来处理实现限制。
我想说前两个概念“唯一性”和“不可减少性”的设计标准比主键的基本属性要少,而后者的“简单性”,“熟悉性”和“稳定性”概念更适合标记设计标准,因为它们涉及权衡和主观性。
为什么选择主键?简单和熟悉不仅是选择可用候选密钥的标准,而且也是我们应该选择主密钥的原因。如果表中有多个候选键,则如果指向该表的所有外键都引用相同的候选键,则会简化操作。此外,选择特定候选键的行为将有助于使其熟悉。
答案 8 :(得分:2)
有什么标准?
PRIMARY KEY
是定义实体的东西,只定义实体而不是实体。
你可以从外面看世界。比如说,一个明星目录号来识别一个明星(很好的例子),或一个SSN
来识别一个人(坏例子)。
在这种情况下,你依赖外部世界。
SSN
吗? (他们没有)。SSN
的独特之处是什么? (他们不是)。SSN
分配给其他人吗? (它可以)。您可以使用AUTOINCREMENT
或GUIDs
或其他任何方式在模型中生成它。
在这种情况下,您依靠自己和数据库技能。
ID
吗? (是的,他们这样做,否则他们不会在ID NOT NULL
)的表格中。ID's
是唯一的吗? (是的,它们是PRIMARY KEY
约束来处理它)。或另一组答案:
ID
吗? (不,他们没有,人员表被意外删除,但保留了一些其他信息)。ID's
是唯一的吗? (不,我们无法正确合并数据库的两个版本。)AUTOINCREMENT
。)最重要的是,代理钥匙是一个永远伴随着你的盛宴。您始终可以创建代理键:地球上的任何内容都不能阻止您声明AUTOINCREMENT
字段。但到目前为止,并非所有事情都有某种标识符,每个人都同意。
然而,一个好的自然键不能过分强调。
Guide Star Catalog
数据库最有可能比您的数据库更可靠地备份,并且您始终可以从内存中恢复US
状态代码列表。
答案 9 :(得分:1)
实际上只有一个,为每个表选择代理(身份/自动编号)或类似用户永远不会看到的东西,这样你就可以随时随地为他们做任何必要的事情。
答案 10 :(得分:1)
(不太确定如何解释这个问题。听起来像是一个测验或者你正在寻找教科书中一个单一“正确”答案的东西。我将把这个问题解释为一个更实用的问题,因此我的以下建议。)
至少在MS SQL世界中,关于正确的主键的讨论不可避免地包含在关于表的正确聚簇索引的讨论中。这两个没有是相同的,但它们是默认的,对于许多表来说,使两者相同通常是一个好主意。
为了我们在此讨论的目的,区分两者很重要:
PRIMARY KEY 是唯一标识行的字段或字段组合 CLUSTERED INDEX 是表示表的物理排序的字段或字段组合。 (同样,我说的是MS SQL Server,不确定其他RDBS如何处理这个问题)
我讨论的其余部分的关键是知道自SQL 7.0以来,聚簇索引键用作所有非聚簇索引的行标识符。这意味着选择一个好的聚类键的许多相同标准与选择一个好的主键相同。
让我们首先看一下好的聚集索引的标准(来自Kimberly Tripp's excellent article)。聚集索引应为:
很明显,前3个也是主键的良好标准。 #4是一个奖励,可以随着表的增长减少表碎片。
作为主键的GUID,实际上是这两个标准(Narrow and Ever-Increase)实际上失败了。因此,在大多数情况下不建议将其作为PK /聚集索引(参见Kim的related article here)
答案 11 :(得分:-2)
我会在这里说一些不合预期的事。
在选择主键时,他们在数据库中教授的有关规范化和键的所有内容都是错误的。
在范围查询方面,主键是特殊的,因此,如果您的主键范围查询是主键,则没有例外。
如果您的显性范围查询不在候选键上,那么您最终会得到一个不对唯一性强制执行的主键!这有时被称为聚集索引,由于没有索引,因此用词不当。
现在规范化和候选键都很重要,您将希望至少对其中一些强制执行唯一约束。但是不要分配主键,因为它是自然键。实际上,这比定义索引和唯一约束要慢。仅基于范围查询定义主键。
请记住,实际拥有主键没有任何限制。没有主键的表称为堆表,并且没有内部排序或插入顺序内部排序。
编辑:范围查询的定义:
范围查询是ORDER BY查询的查询,或包含大于或小于运算符的查询。我们感兴趣的是运行这些查询的列。基本思想是一个范围查询根据一端或两端的边界条件从表中提取几个(几十到几百到几千但不是全部)行。
还有另一种范围查询,那就是你有另一个表的外键,并且操作是选择所有匹配的外键。事实上,这也是一个范围查询,尽管不是很明显。