如何在关系中设置主键?
How to set up Primary Keys in a Relation?
我想知道如何在关系中正确设置主键。例如。我们有 ER 图,其中包含元素:
- 关键属性
- 弱键属性
- 识别关系
- 关联实体
为了将其转化为关系模型,我们应该采取一些技巧。上面的所有元素都处理关系的主键,但它们都是 自然键 - 因此我们可以将它们 保持原样 或替换为 代理键.
考虑一些情况。
案例一
密钥属性 是一个名称 - 因此它必须是 CHAR
或 VARCHAR
类型。通常名称会变成 Key Attributes.
案例二
两个(或更多)识别关系成为关系的复合主键(由外键).
案例三
识别具有弱键属性的关系也成为复合主键.
案例4
关联实体通常有两个或更多识别关系,因此它们是连接关系(连接Tables)。
如何为Relations设置主键以处理上述所有情况(也许还有一些我没有提到的情况)?
如何避免使用代理键以及在哪些情况下它们是必要的?
如何设置主键的数据类型?
如果必须将复合主键传递给子关系,是否应将其替换为代理项?
我认为使用代理键的优点和缺点:
优势
它们很紧凑(通常是 INT
类型),有时可以很好地替代组合键
它们在 外键
中时是说明性的
它们被轻松编入索引
缺点
它们是数字,毫无意义。例如。我希望在我的界面应用程序中填写 Junction Table - 所以我别无选择,只能关联数字
它们是多余的
他们很困惑
至于设置数据类型- 必须有更多的技巧以及设置整体主键。
更新
我本来应该举个例子的,但我没有。所以这是一个例子。
考虑到我们有两个相互交互的主要实体(仍然不知道如何在这里说明诸如图表之类的东西 - 所以我将它们显示为 tables 以展示国际 Space 站船员轮换制度):
SpaceShip
╔════════════════╤════════════════╗
║ ShipName │ ShipType ║ ShipName - Primary Key
╟────────────────┼────────────────╢ ShipType - Foreign Key (but it is
║ Soyuz TMA-14 │ Soyuz ║ not being considered here)
║ Endeavour │ Space Shuttle ║
║ Soyuz TMA-15M │ Soyuz ║
║ Atlantis │ Space Shuttle ║
║ Soyuz TM-31 │ Soyuz ║
║ ... │ ... ║
╚════════════════╧════════════════╝
和 Crew
╔════════╤══════════╗
║ CrewId │ SallSign ║ CrewId - Primary Key (used Id 'case crew is usually
╟────────┼──────────╢ shown as crew members - it has no particular
║ 4243 │ Astreus ║ name)
║ 4344 │ Altair ║ CallSign - attribute (it may not be assigned or
║ 4445 │ ... ║ explicitly shown - i.e. it can be NULL)
║ ... │ ... ║
╚════════╧══════════╝
这两个实体通过 Flight
进行交互。每次飞行向国际空间站运送一名机组人员和 returns 另一名或同一名机组人员。显然Flight
和Crew
之间的关系是多对多的,需要连接关系(table)。但我们不能仅仅将 SpaceShip
和 Crew
联系起来,因为宇宙飞船 - 宇宙飞船可以重复使用(可回收),例如 Space 航天飞机。
所以 Flight
应该是这样的:
╔═══════════════╤════════════╤═══════════════╤═════╗
║ ShipName │ FlightName │ ShipFlightNum │ ... ║ ShipName, FlightName
╟───────────────┼────────────┼───────────────┼─────╢ are composite PK
║ Soyuz TM-31 │ NULL │ 1 │ ... ║ ShipFlightNum
║ Atlantis │ STS-117 │ 28 │ ... ║ depends on whole
║ Soyuz TMA-14 │ NULL │ 1 │ ... ║ Composite PK
║ Endeavour │ STS-126 │ 22 │ ... ║ ... - other
║ Soyuz TMA-15M │ NULL │ 1 │ ... ║ attributes which
║ Endeavour │ STS-111 │ 18 │ ... ║ depend on PK
║ Atlantis │ STS-122 │ 29 │ ... ║
║ ... │ ... │ ... │ ... ║
╚═══════════════╧════════════╧═══════════════╧═════╝
所以Flight
有复合主键(Soyuz飞行器的飞行名称与航天器的名称相同但不同对于可重复使用的航天器,例如 Space Shuttle),它需要与 Crew
关联为多对多。这是我的复杂问题的一部分 - 如果这个复合 Primary Natural Key 应该替换为 Surrogate one?
如果我们要进一步使用 Natural Keys,那么新的 Junction Relation (Associative Entity)应该看起来像:
Designation
(机组人员专为飞行而设计)
╔═══════════════╤════════════╤════════╤══════════╗
║ ShipName │ FlightName │ CrewId │ CrewType ║
╟───────────────┼────────────┼────────┼──────────╢
║ Soyuz TMA-15M │ NULL │ 4243 │ Deliver ║
║ Soyuz TMA-15M │ NULL │ 4243 │ Return ║
║ Soyuz TMA-15M │ NULL │ 4445 │ Backup ║
║ Soyuz TMA-16M │ NULL │ 4344 │ Deliver ║
║ Soyuz TMA-17M │ NULL │ 4445 │ Deliver ║
║ Soyuz TMA-18M │ NULL │ 4344 │ Return ║
║ Endeavour │ STS-111 │ 55 │ Deliver ║
║ Endeavour │ STS-111 │ 44 │ Return ║
║ Endeavour │ STS-113 │ 55 │ Return ║
║ ... │ ... │ ... │ ... ║
╚═══════════════╧════════════╧════════╧══════════╝
这里我们有 4x 复合主键,它由四个 外键 组成(CrewType 也有 FK 约束)。如果我们使用 Surrogates 而不是 Naturals 那么结果会更紧凑但很难填充(在我看来)。
再更新一次
另一个案例 table(关系)TypeCrew
:
╔══════════╗
║ CrewType ║
╟──────────╢
║ Deliver ║
║ Return ║
║ Backup ║
║ ... ║
╚══════════╝
如果我们不必在查询中使用这些值,一切都会好起来的 (WHERE CrewType LIKE 'Backup'
)。如果这些值将被替换为其他语言的替代含义,甚至替换为符号,例如>
、<
和 ^
分别表示 Deliver
、Return
和 Backup
(WHERE CrewType LIKE '^'
)。添加数字 代理键 将无济于事,因为它的值可能与 TypeName
(WHERE TypeId=2
):
不匹配
╔════════╤══════════╗ ╔════════╤══════════╗ ╔════════╤══════════╗
║ TypeId │ TypeName ║ ║ TypeId │ TypeName ║ ║ TypeId │ TypeName ║
╟────────┼──────────╢ ╟────────┼──────────╢ ╟────────┼──────────╢
║ 0 │ Deliver ║ ║ 0 │ Backup ║ ║ 0 │ > ║
║ 1 │ Return ║ ║ 1 │ Deliver ║ ║ 1 │ < ║
║ 2 │ Backup ║ ║ 2 │ Return ║ ║ 2 │ ^ ║
║ ... │ ... ║ ║ ... │ ... ║ ║ ... │ ... ║
╚════════╧══════════╝ ╚════════╧══════════╝ ╚════════╧══════════╝
难道这不是关系模型的问题?也许这只是糟糕的设计?但我想不出更好的办法了。
您列出的使用代理键的优缺点很好。正如该列表所暗示的,这个主题是一个复杂的主题。对于何时指示或禁止代理键,数据库设计者之间没有统一的共识。即使在这个问答区,您也会发现关于这个主题的不同意见。
我对您列出的 "meaningless" 表示使用代理键不利。在许多情况下,它们毫无意义的事实是一种优势,而不是劣势。特别是很多人发明的自然键并不是"atomic"。也就是说,它们包含在密钥内编码的多个属性。
例如,是否可以根据车辆的 VIN(车辆识别码)确定车辆的乘客座位数。但这是最初制造的座位数,不一定是当前时间点的座位数。由于 VIN 应该是不可变的,所以当一个座位被撕掉时它不能改变。现在它具有误导性。
那么多数据库设计老师提倡无意义的键。
有几个您没有提到的用作自然键的名称的缺点。它们通常不是唯一的,而且它们通常是可变的,正如人类所使用的那样。例如,一所大学可能有两个学生,他们的名字叫 Mary Jones。或者 Mary Jones 可能会在学期中途将她的名字更改为 Mary Smith。
还有一个你没有提到的缺点。这是误导的数据,包括欺诈。如果 SSN 用于识别员工身份,我们必须防止员工给我们一个假的 SSN,然后雇用真正拥有该 SSN 的人。那时数据库真的有问题了。
这个答案只涉及一个非常大的话题的几个方面。我建议进一步阅读 CJ Date 等作者的文章。
位置
任何没有建立在坚实理论基础上的实践都是不值得考虑的。我是一名严格的关系模型实践者,理论基础扎实。 关系模型基于坚实的理论,从未被反驳过1。 "relational theory" 没有任何根据,我接受了他们,并在他们的 space 中驳斥了他们的观点。此外,关系数据库设计是一门科学,不是魔术,不是艺术2,因此我可以为我提出的任何主张或指控提供证据。我的答案来自那个位置。
1.都是non-science篇文章,一堆不懂科学的人的意见,是的,但没有科学反驳。就像侏儒说人不会飞一样,对他们来说"true",对人类来说就不是这样了,这是建立在完全无法理解飞行原理的基础上
2。 high-end 从业者的演讲中有一些艺术,是的,但这并不能使科学成为艺术。它是一门科学,而且只是一门科学,除此之外,它还可以在模型和数据库中巧妙地传递。
"Relational Theory"
I wish to know how to correctly set up Primary Keys in a Relation. E.g. we have ER-diagram which contain elements:
如果它是一个 ERD,那么您将不会查看 "relations",您会查看实体(如果图表是早期的)或 tables(如果它是有进展的) ). "Relations" 是一个很棒的抽象,与实现无关。 ERD 或数据模型意味着实现(non-abstract,真实的)是有意的,物理的意图将理论的抽象世界抛在脑后,并进入物理世界,在那里愚蠢的抽象被摧毁。
此外,声称为数据库 space 服务的 "theoreticians" 无法区分基本关系和派生关系:虽然在抽象上下文中这可能是 acceptable,但它是在实施环境中完全错误。例如。基础关系是tables,他们需要被归一化;派生关系是基本关系的派生视图,根据定义,基本关系是 扁平化视图 (不是 "denormalised",意思略有不同)。因此,它们不需要标准化。
- 但是"theoreticians"尝试"normalise"导出关系。受损最严重的两个人试图拥有 1NF 的定义,我们已经有 45 年了,这是基本的和坚如磐石的,他们自己支持,改变,因此他们的派生关系不需要 "normalisation",可以分类为"normalised"。如果不是那么悲伤,那就太好笑了。
objective 科学真理的一个奇妙品质是它不会改变。主观"truth",non-science,一直在变。一个可以依靠,在实践之前必须了解它,另一个不值得阅读。
隔离
他们生活在自己的世界中,与关系数据库的现实隔离开来,特别是关系模型,以及他们声称服务的行业。在 RM 出现后的四十五年里,他们没有做任何事情来改进 RM 或关系数据库。
请注意,他们一直在推进各种概念,这些概念在 关系模型 之外。
RM(尼安德特人提出的 "incomplete" 的完成)的进展完全是由于标准化(R Brown 和其他人与 Codd 合作,产生了 IDEF1X 关系数据库建模标准),以及 high-end SQL 供应商及其客户的努力。
那是商业 RDBMS 供应商,他们已经在 1980 年代成立,而不是过去十年的 Non-sql freeware/shareware/vapourware 组,他们将他们的产品作为 "sql",这让你很好,并粘在他们的 "platform",non-portable。
最糟糕的是,他们出版了关于他们 non-relational 概念的书籍,并以欺骗性的方式将它们标记为 "relational"。而且"professors"盲目地"teach"这些废话,像鹦鹉学舌一样,既不理解这些废话,也不理解它应该探索的关系模型。
如果您正在尝试寻找某些 "educational" 项目的答案,抱歉,我无法提供,因为如您所见,"education" 完全混乱,并且有 non-relational 要求。
然而,我可以直接回答这个问题,受科学、关系模型、物理定律等的支配
从中得出的要点是,在 E F Codd 博士发表他的开创性著作之后,关系理论和实践非常接近,并且在供应商开发 SQL 平台期间,在post-Codd时代,通称"relational theory"的东西完全脱离了原来的关系论。
- 我可以列举不同之处,但这里不能。请注意,如果您阅读我涉及此主题的帖子,您可以收集这些细节,并自己列举它们。或者问一个新问题。
问题
I wish to know how to correctly set up Primary Keys in a Relation. E.g. we have ER-diagram which contain elements:
没有要检查的 ERD。好的,在更新中你有一个例子。非常适合您的问题,因为它是一组用户数据视图,现在可以开始建模了。但请注意,这不是 ERD 或模型。我们依赖于对数据的理解;分析它;对其进行分类,而不是用显微镜查看数据 values。我知道这就是你被教导要做的。
In order to translate it into Relational Model
是的,这就是既定目标。 "translate" 这个词是不正确的,因为 RM 不仅仅是一个 "satisfies" 或适合的一组固定或固定的标准(因为它是众所周知的"theoreticians"),它还提供了具体的方法和规则。因此,我们将建模,根据Relational Model.
we should do some tricks.
我们不需要技巧,我们用科学,而且只用科学。 "theoreticians"和跟随他们的"professors",需要技巧,练习non-science。在这方面我无能为力。此外,他们使用的技巧通常是规避和颠覆关系模型,所以要小心他们。
代理人
All elements above deal with Primary Keys of relations but they all are Natural Keys - so we can leave them as is or replace with Surrogate Keys.
嗯,就是这样,你的"teacher's"第一招暴露了。
代理项是物理记录(不是行)指针,它们不是逻辑的。
没有"surrogate key",这两个词自相矛盾。
一个Key在RM中有具体定义,必须由数据组成。替代品不是由数据组成的,它是制造出来的,是系统生成的无意义的数字。因此它不是密钥或 "key"。
RM 中的一个键具有许多关系特性,这使得键非常强大。由于代理不是密钥,它没有任何这些品质,它没有关系力。
因此,"surrogate"和Key各有其特定的含义,作为单独的名词还好,但合起来就是self-contradictory,因为它们是相反的。
当人们使用术语 "surrogate key" 时,他们自然会期待钥匙的某些(如果不是全部)品质。但他们不会得到其中的任何一个。所以他们被骗了。
关系模型(理论家一无所知的模型)有一个特定的访问路径独立规则 .只要使用关系键,就会维护此规则。它提供关系完整性 1。
代理的使用违反了这条规则。结果 2 是,关系完整性和关系导航 3 都丢失了。
其结果是,需要更多的连接才能获得相同的数据(不少,因为神话和魔法爱好者不断鹦鹉学舌)。
因此,在另一个单独的计数中,不允许代孕。
由于您处于建模阶段,无论是概念还是逻辑,并且键是逻辑的,代理是物理的,代理不应该出现在画面中。 (只有当逻辑模型完成并且正在考虑物理模型时,它们才会出现,如果有的话,只是为了考虑。)你离逻辑模型的完成还差得很远,所以引入代理应该引起红色旗帜。
"teacher" 和他正在使用的 "textbook" 的作者是欺诈,有两个不同的罪名:
他们在逻辑练习中引入了一个物理场,它不应该关注数据库的物理方面。
但这样做的结果是,他们建立代理人,即物理事物,作为合乎逻辑的事物。因此他们毒害了思想。
在那里,直截了当的科学,纯粹的逻辑,没有被疯狂的思想所污染,因此不受欺诈的影响。逻辑阶段没有代理人。
1.关系完整性(关系模型提供)与参照完整性(SQL提供,记录归档系统可能有明显不同).如果你不明白这一点,请打开一个新问题 "What is the difference ..." 并 ping 我。
2。违反任何规则总是会产生不良后果,而不仅仅是行为本身。
3。如果你不明白这一点,请打开一个新问题 "What is the Relational Navigation ..." 并 ping 我。
所以你问题的最终答案:
All elements above deal with Primary Keys of relations but they all are Natural Keys - so we can leave them as is or replace with Surrogate Keys.
在概念和逻辑练习中,我们只处理逻辑键。代孕等物理概念是非法的。在逻辑练习中,用物理生物替换逻辑键被拒绝。使用您拥有的密钥,这些密钥来自数据,而且很自然。
不是 "Replacement"
还有一点。术语 "replacement" 不正确。代理永远不会替代或替代自然密钥。
自然键提供的众多品质之一是行唯一性,关系模型也需要这一点,不允许重复行。
由于代理项不是行的键(它是指向记录的物理指针),因此它无法提供所需的行唯一性。如果你不完全明白我在说什么,请阅读 this Answer,从顶部到 False Teachers。测试给定的代码练习。
因此,在物理建模阶段,即使考虑了代理项,也始终是附加列和索引。它不是自然关系键的替代品。
并且相反,如果代理 是 作为替换实现的,结果是重复行,non-relational 文件,而不是关系 table.
案例一
Key Attribute is a name - so it must be of type CHAR or VARCHAR. Generally names become Key Attributes.
是的。
通常它们是代码(用户确实使用代码)。 Codes 通常会跳到你面前(你在 One More Update 中有一个很好的例子)。 { D |右 | B } 也一样 { < | ^ | > }。这当然是接近逻辑模型阶段的末尾,此时模型为 stable,并且正在完成 Keys 并对其进行优化。对于早于此的任何阶段,宽自然键都有效。
我们的想法是让它有意义。
键有意义(代理没有意义)。关系键的一个特性是,无论键作为外键迁移到哪里,它的含义都会被传递。
并且根据您的示例,无论在何处使用。包括程序代码。写作:
IF CrewType = "Backup" -- meaningful but fixes a value
IF CrewType = 1 -- meaningless
完全错误。因为(a)那不是真正的键,并且(b)用户很可能将该数据的值从 Backup
更改为 Reserve
,等等。永远不要编写寻址数据值的代码,a描述符。所以事实是,Backup
是Key的投影,exposition,代码是Key。解析为 CrewType.Name,密钥为 CrewTypeCode。
IF CrewTypeCode = "B" -- Key, meaningful, not fixed
当我们使用 Keys 时,请注意:
在关系模型中,我们有主键、备用键和外键(迁移的主键)。
我们没有"candidate keys",RM中没有定义这样的东西。是RM以外制造的东西。因此是non-relational。
更糟糕的是,它们被实施代理的人用作 "primary keys" a.
一种身体上的考虑 b,但应该在整个练习中理解和应用。当数据被理解和已知时,列将是固定长度的。当它们未知时,它们可能是可变的。对于键,考虑到它们将被索引,至少在主端,它们永远不应该是可变的,因为这需要在每次访问时解包。
一个。使用 SQL 关键字 PRIMARY KEY
不会神奇地将代理项转换为 PK。如果一个遵循RM,一个(a)确定可能的Keys(无代理),然后(b)选择一个作为Primary,这(c)意味着选举结束,因此(d) 提名的候选人不能再称为 "candidates",事件已成为历史,因此 (e) 其余的 non-primary 密钥是备用密钥。
"Candidate key"是拒绝符合RM而提名一个PK,因此,就其本身而言,它是non-relational.除了他们有一个替代品 "primary key",这是第二个 non-relational 项。
b.对于那些 non-technical 认为没有技术知识和远见,根本没有物理考虑的人,应该在逻辑上进行评估,没关系,在物理上评估他们。由于我不是在这里解决物理问题,所以我只是为 Umbra 做个笔记。
魔术师们凭借自己的魔术,让小兔变成了狮子。科学家不需要它们。
案例二
Two (or more) Identifying Relationships become a Composite Primary Key of a relation (which is made of Foreign Keys).
我认为您的想法是正确的,但对于一般情况,措辞不正确。
该措辞对于具有两个外键的 关联 Table 是正确的。是的,在那种情况下,两个 FK 形成了 PK,这就是行唯一性所需要的。没有比这更好的了。添加记录 ID 是多余的。
对于一般情况,对于任何 table:
一个识别关系 1导致FK(迁移parent PK)成为child中的PK。因此名称 parent 标识 child.
这使得 child 成为 Dependent 1 table,这意味着child 行只能存在于 parent 行的上下文中。这样的 table 形成数据层次结构中的中间节点和叶节点,它们是关系数据库中 table 的大部分。
如果行可以独立存在,则table是独立1。这样的 table 构成了每个数据层次结构的顶部,在关系数据库中很少见。
A Non-identifying关系 1是FK(迁移parent PK), 不用于形成 child PK.
复合或复合键只是由不止一列组成,它们是关系数据库中的标准票价。除了每个数据层次结构的顶部外,每个 table 都有一个复合键。如果没有,则数据库不是关系型的。
请仔细阅读我的IDEF1X Introduction
1. "theoreticians" 不区分 Identifying 与 Non-identifying,或 Dependent 与 Independent:他们所有的文件都是 Independent;记录指针之间的所有 "relationships" 都是 Non-identifying。它是对 1970 年代之前的 ISAM 记录归档系统的倒退,缺乏关系完整性、功能和速度。这就是他们所了解的,这就是他们所能教导的。欺诈性地标记为 "relational".
案例三
Identifying Relationship(s) with Weak Key Attribute(s) also become a Composite Primary Key.
与 "key" 有或没有关系的术语 "weak" 未在 关系模型 中定义。这是"theoreticians"的小说。所以我无法回答这个问题。
我确实注意到一些 "theoretical" 论文将 strong Keys(正常的英文单词,描述 Key 之前已经建立的事实)呈现为 "weak",并且weak "keys"(正常的英文单词,描述"key"之前没有成立的事实)为"strong"。这就是精神分裂症的本质。
因此,我怀疑这是他们试图将科学与 non-science 混淆并破坏 关系模型 的一部分.在过去,当这样的人被关起来时,人类是健康的。现在他们在大学里写书和教书。
案例4
Associative entities usually have two or more Identifying Relationships
是的。两个是正确的。
如果你有两个以上,那就是没有完全归一化。 Codd 给出了一个明确的规范化方法,这样就会有两个(或更多)关联实体,每个实体都有两个完全识别的关系。
- "...因此,所有 n-ary(多于两个)关系...可以...而且应该解析为二元(两个)关系。"
(为此上下文改写)
so they are to be Junction Relations (Junction Tables).
没有。 "Junction" 关系和 "junction" table 未在 关系模型 中定义,因此它们是 non-relational。
逻辑中的关联实体在物理中变为关联 Table。
回答太长
答案的完成超出了 SO 答案的限制。因此,我将答案放在一个文档中,并提供了 link。在这一点上拆分答案被证明是一种罪过,因此文档包含完整的答案,具有一致的格式等:
要从这一点继续(即上面的 SO 答复文本),只需向下滚动到 案例 4 标题。
保留上述 SO Answer 文本是有价值的,不仅用于历史目的,还用于文本搜索等。
我想知道如何在关系中正确设置主键。例如。我们有 ER 图,其中包含元素:
- 关键属性
- 弱键属性
- 识别关系
- 关联实体
为了将其转化为关系模型,我们应该采取一些技巧。上面的所有元素都处理关系的主键,但它们都是 自然键 - 因此我们可以将它们 保持原样 或替换为 代理键.
考虑一些情况。
案例一
密钥属性 是一个名称 - 因此它必须是 CHAR
或 VARCHAR
类型。通常名称会变成 Key Attributes.
案例二
两个(或更多)识别关系成为关系的复合主键(由外键).
案例三
识别具有弱键属性的关系也成为复合主键.
案例4
关联实体通常有两个或更多识别关系,因此它们是连接关系(连接Tables)。
如何为Relations设置主键以处理上述所有情况(也许还有一些我没有提到的情况)?
如何避免使用代理键以及在哪些情况下它们是必要的?
如何设置主键的数据类型?
如果必须将复合主键传递给子关系,是否应将其替换为代理项?
我认为使用代理键的优点和缺点:
优势
它们很紧凑(通常是
INT
类型),有时可以很好地替代组合键它们在 外键
中时是说明性的
它们被轻松编入索引
缺点
它们是数字,毫无意义。例如。我希望在我的界面应用程序中填写 Junction Table - 所以我别无选择,只能关联数字
它们是多余的
他们很困惑
至于设置数据类型- 必须有更多的技巧以及设置整体主键。
更新
我本来应该举个例子的,但我没有。所以这是一个例子。 考虑到我们有两个相互交互的主要实体(仍然不知道如何在这里说明诸如图表之类的东西 - 所以我将它们显示为 tables 以展示国际 Space 站船员轮换制度):
SpaceShip
╔════════════════╤════════════════╗
║ ShipName │ ShipType ║ ShipName - Primary Key
╟────────────────┼────────────────╢ ShipType - Foreign Key (but it is
║ Soyuz TMA-14 │ Soyuz ║ not being considered here)
║ Endeavour │ Space Shuttle ║
║ Soyuz TMA-15M │ Soyuz ║
║ Atlantis │ Space Shuttle ║
║ Soyuz TM-31 │ Soyuz ║
║ ... │ ... ║
╚════════════════╧════════════════╝
和 Crew
╔════════╤══════════╗
║ CrewId │ SallSign ║ CrewId - Primary Key (used Id 'case crew is usually
╟────────┼──────────╢ shown as crew members - it has no particular
║ 4243 │ Astreus ║ name)
║ 4344 │ Altair ║ CallSign - attribute (it may not be assigned or
║ 4445 │ ... ║ explicitly shown - i.e. it can be NULL)
║ ... │ ... ║
╚════════╧══════════╝
这两个实体通过 Flight
进行交互。每次飞行向国际空间站运送一名机组人员和 returns 另一名或同一名机组人员。显然Flight
和Crew
之间的关系是多对多的,需要连接关系(table)。但我们不能仅仅将 SpaceShip
和 Crew
联系起来,因为宇宙飞船 - 宇宙飞船可以重复使用(可回收),例如 Space 航天飞机。
所以 Flight
应该是这样的:
╔═══════════════╤════════════╤═══════════════╤═════╗
║ ShipName │ FlightName │ ShipFlightNum │ ... ║ ShipName, FlightName
╟───────────────┼────────────┼───────────────┼─────╢ are composite PK
║ Soyuz TM-31 │ NULL │ 1 │ ... ║ ShipFlightNum
║ Atlantis │ STS-117 │ 28 │ ... ║ depends on whole
║ Soyuz TMA-14 │ NULL │ 1 │ ... ║ Composite PK
║ Endeavour │ STS-126 │ 22 │ ... ║ ... - other
║ Soyuz TMA-15M │ NULL │ 1 │ ... ║ attributes which
║ Endeavour │ STS-111 │ 18 │ ... ║ depend on PK
║ Atlantis │ STS-122 │ 29 │ ... ║
║ ... │ ... │ ... │ ... ║
╚═══════════════╧════════════╧═══════════════╧═════╝
所以Flight
有复合主键(Soyuz飞行器的飞行名称与航天器的名称相同但不同对于可重复使用的航天器,例如 Space Shuttle),它需要与 Crew
关联为多对多。这是我的复杂问题的一部分 - 如果这个复合 Primary Natural Key 应该替换为 Surrogate one?
如果我们要进一步使用 Natural Keys,那么新的 Junction Relation (Associative Entity)应该看起来像:
Designation
(机组人员专为飞行而设计)
╔═══════════════╤════════════╤════════╤══════════╗
║ ShipName │ FlightName │ CrewId │ CrewType ║
╟───────────────┼────────────┼────────┼──────────╢
║ Soyuz TMA-15M │ NULL │ 4243 │ Deliver ║
║ Soyuz TMA-15M │ NULL │ 4243 │ Return ║
║ Soyuz TMA-15M │ NULL │ 4445 │ Backup ║
║ Soyuz TMA-16M │ NULL │ 4344 │ Deliver ║
║ Soyuz TMA-17M │ NULL │ 4445 │ Deliver ║
║ Soyuz TMA-18M │ NULL │ 4344 │ Return ║
║ Endeavour │ STS-111 │ 55 │ Deliver ║
║ Endeavour │ STS-111 │ 44 │ Return ║
║ Endeavour │ STS-113 │ 55 │ Return ║
║ ... │ ... │ ... │ ... ║
╚═══════════════╧════════════╧════════╧══════════╝
这里我们有 4x 复合主键,它由四个 外键 组成(CrewType 也有 FK 约束)。如果我们使用 Surrogates 而不是 Naturals 那么结果会更紧凑但很难填充(在我看来)。
再更新一次
另一个案例 table(关系)TypeCrew
:
╔══════════╗
║ CrewType ║
╟──────────╢
║ Deliver ║
║ Return ║
║ Backup ║
║ ... ║
╚══════════╝
如果我们不必在查询中使用这些值,一切都会好起来的 (WHERE CrewType LIKE 'Backup'
)。如果这些值将被替换为其他语言的替代含义,甚至替换为符号,例如>
、<
和 ^
分别表示 Deliver
、Return
和 Backup
(WHERE CrewType LIKE '^'
)。添加数字 代理键 将无济于事,因为它的值可能与 TypeName
(WHERE TypeId=2
):
╔════════╤══════════╗ ╔════════╤══════════╗ ╔════════╤══════════╗
║ TypeId │ TypeName ║ ║ TypeId │ TypeName ║ ║ TypeId │ TypeName ║
╟────────┼──────────╢ ╟────────┼──────────╢ ╟────────┼──────────╢
║ 0 │ Deliver ║ ║ 0 │ Backup ║ ║ 0 │ > ║
║ 1 │ Return ║ ║ 1 │ Deliver ║ ║ 1 │ < ║
║ 2 │ Backup ║ ║ 2 │ Return ║ ║ 2 │ ^ ║
║ ... │ ... ║ ║ ... │ ... ║ ║ ... │ ... ║
╚════════╧══════════╝ ╚════════╧══════════╝ ╚════════╧══════════╝
难道这不是关系模型的问题?也许这只是糟糕的设计?但我想不出更好的办法了。
您列出的使用代理键的优缺点很好。正如该列表所暗示的,这个主题是一个复杂的主题。对于何时指示或禁止代理键,数据库设计者之间没有统一的共识。即使在这个问答区,您也会发现关于这个主题的不同意见。
我对您列出的 "meaningless" 表示使用代理键不利。在许多情况下,它们毫无意义的事实是一种优势,而不是劣势。特别是很多人发明的自然键并不是"atomic"。也就是说,它们包含在密钥内编码的多个属性。
例如,是否可以根据车辆的 VIN(车辆识别码)确定车辆的乘客座位数。但这是最初制造的座位数,不一定是当前时间点的座位数。由于 VIN 应该是不可变的,所以当一个座位被撕掉时它不能改变。现在它具有误导性。
那么多数据库设计老师提倡无意义的键。
有几个您没有提到的用作自然键的名称的缺点。它们通常不是唯一的,而且它们通常是可变的,正如人类所使用的那样。例如,一所大学可能有两个学生,他们的名字叫 Mary Jones。或者 Mary Jones 可能会在学期中途将她的名字更改为 Mary Smith。
还有一个你没有提到的缺点。这是误导的数据,包括欺诈。如果 SSN 用于识别员工身份,我们必须防止员工给我们一个假的 SSN,然后雇用真正拥有该 SSN 的人。那时数据库真的有问题了。
这个答案只涉及一个非常大的话题的几个方面。我建议进一步阅读 CJ Date 等作者的文章。
位置
任何没有建立在坚实理论基础上的实践都是不值得考虑的。我是一名严格的关系模型实践者,理论基础扎实。 关系模型基于坚实的理论,从未被反驳过1。 "relational theory" 没有任何根据,我接受了他们,并在他们的 space 中驳斥了他们的观点。此外,关系数据库设计是一门科学,不是魔术,不是艺术2,因此我可以为我提出的任何主张或指控提供证据。我的答案来自那个位置。
1.都是non-science篇文章,一堆不懂科学的人的意见,是的,但没有科学反驳。就像侏儒说人不会飞一样,对他们来说"true",对人类来说就不是这样了,这是建立在完全无法理解飞行原理的基础上
2。 high-end 从业者的演讲中有一些艺术,是的,但这并不能使科学成为艺术。它是一门科学,而且只是一门科学,除此之外,它还可以在模型和数据库中巧妙地传递。
"Relational Theory"
I wish to know how to correctly set up Primary Keys in a Relation. E.g. we have ER-diagram which contain elements:
如果它是一个 ERD,那么您将不会查看 "relations",您会查看实体(如果图表是早期的)或 tables(如果它是有进展的) ). "Relations" 是一个很棒的抽象,与实现无关。 ERD 或数据模型意味着实现(non-abstract,真实的)是有意的,物理的意图将理论的抽象世界抛在脑后,并进入物理世界,在那里愚蠢的抽象被摧毁。
此外,声称为数据库 space 服务的 "theoreticians" 无法区分基本关系和派生关系:虽然在抽象上下文中这可能是 acceptable,但它是在实施环境中完全错误。例如。基础关系是tables,他们需要被归一化;派生关系是基本关系的派生视图,根据定义,基本关系是 扁平化视图 (不是 "denormalised",意思略有不同)。因此,它们不需要标准化。
- 但是"theoreticians"尝试"normalise"导出关系。受损最严重的两个人试图拥有 1NF 的定义,我们已经有 45 年了,这是基本的和坚如磐石的,他们自己支持,改变,因此他们的派生关系不需要 "normalisation",可以分类为"normalised"。如果不是那么悲伤,那就太好笑了。
objective 科学真理的一个奇妙品质是它不会改变。主观"truth",non-science,一直在变。一个可以依靠,在实践之前必须了解它,另一个不值得阅读。
隔离
他们生活在自己的世界中,与关系数据库的现实隔离开来,特别是关系模型,以及他们声称服务的行业。在 RM 出现后的四十五年里,他们没有做任何事情来改进 RM 或关系数据库。
请注意,他们一直在推进各种概念,这些概念在 关系模型 之外。
RM(尼安德特人提出的 "incomplete" 的完成)的进展完全是由于标准化(R Brown 和其他人与 Codd 合作,产生了 IDEF1X 关系数据库建模标准),以及 high-end SQL 供应商及其客户的努力。
那是商业 RDBMS 供应商,他们已经在 1980 年代成立,而不是过去十年的 Non-sql freeware/shareware/vapourware 组,他们将他们的产品作为 "sql",这让你很好,并粘在他们的 "platform",non-portable。
最糟糕的是,他们出版了关于他们 non-relational 概念的书籍,并以欺骗性的方式将它们标记为 "relational"。而且"professors"盲目地"teach"这些废话,像鹦鹉学舌一样,既不理解这些废话,也不理解它应该探索的关系模型。
如果您正在尝试寻找某些 "educational" 项目的答案,抱歉,我无法提供,因为如您所见,"education" 完全混乱,并且有 non-relational 要求。
然而,我可以直接回答这个问题,受科学、关系模型、物理定律等的支配
从中得出的要点是,在 E F Codd 博士发表他的开创性著作之后,关系理论和实践非常接近,并且在供应商开发 SQL 平台期间,在post-Codd时代,通称"relational theory"的东西完全脱离了原来的关系论。
- 我可以列举不同之处,但这里不能。请注意,如果您阅读我涉及此主题的帖子,您可以收集这些细节,并自己列举它们。或者问一个新问题。
问题
I wish to know how to correctly set up Primary Keys in a Relation. E.g. we have ER-diagram which contain elements:
没有要检查的 ERD。好的,在更新中你有一个例子。非常适合您的问题,因为它是一组用户数据视图,现在可以开始建模了。但请注意,这不是 ERD 或模型。我们依赖于对数据的理解;分析它;对其进行分类,而不是用显微镜查看数据 values。我知道这就是你被教导要做的。
In order to translate it into Relational Model
是的,这就是既定目标。 "translate" 这个词是不正确的,因为 RM 不仅仅是一个 "satisfies" 或适合的一组固定或固定的标准(因为它是众所周知的"theoreticians"),它还提供了具体的方法和规则。因此,我们将建模,根据Relational Model.
we should do some tricks.
我们不需要技巧,我们用科学,而且只用科学。 "theoreticians"和跟随他们的"professors",需要技巧,练习non-science。在这方面我无能为力。此外,他们使用的技巧通常是规避和颠覆关系模型,所以要小心他们。
代理人
All elements above deal with Primary Keys of relations but they all are Natural Keys - so we can leave them as is or replace with Surrogate Keys.
嗯,就是这样,你的"teacher's"第一招暴露了。
代理项是物理记录(不是行)指针,它们不是逻辑的。
没有"surrogate key",这两个词自相矛盾。
一个Key在RM中有具体定义,必须由数据组成。替代品不是由数据组成的,它是制造出来的,是系统生成的无意义的数字。因此它不是密钥或 "key"。
RM 中的一个键具有许多关系特性,这使得键非常强大。由于代理不是密钥,它没有任何这些品质,它没有关系力。
因此,"surrogate"和Key各有其特定的含义,作为单独的名词还好,但合起来就是self-contradictory,因为它们是相反的。
当人们使用术语 "surrogate key" 时,他们自然会期待钥匙的某些(如果不是全部)品质。但他们不会得到其中的任何一个。所以他们被骗了。
关系模型(理论家一无所知的模型)有一个特定的访问路径独立规则 .只要使用关系键,就会维护此规则。它提供关系完整性 1。
代理的使用违反了这条规则。结果 2 是,关系完整性和关系导航 3 都丢失了。
其结果是,需要更多的连接才能获得相同的数据(不少,因为神话和魔法爱好者不断鹦鹉学舌)。
因此,在另一个单独的计数中,不允许代孕。
由于您处于建模阶段,无论是概念还是逻辑,并且键是逻辑的,代理是物理的,代理不应该出现在画面中。 (只有当逻辑模型完成并且正在考虑物理模型时,它们才会出现,如果有的话,只是为了考虑。)你离逻辑模型的完成还差得很远,所以引入代理应该引起红色旗帜。
"teacher" 和他正在使用的 "textbook" 的作者是欺诈,有两个不同的罪名:
他们在逻辑练习中引入了一个物理场,它不应该关注数据库的物理方面。
但这样做的结果是,他们建立代理人,即物理事物,作为合乎逻辑的事物。因此他们毒害了思想。
在那里,直截了当的科学,纯粹的逻辑,没有被疯狂的思想所污染,因此不受欺诈的影响。逻辑阶段没有代理人。
1.关系完整性(关系模型提供)与参照完整性(SQL提供,记录归档系统可能有明显不同).如果你不明白这一点,请打开一个新问题 "What is the difference ..." 并 ping 我。
2。违反任何规则总是会产生不良后果,而不仅仅是行为本身。
3。如果你不明白这一点,请打开一个新问题 "What is the Relational Navigation ..." 并 ping 我。
所以你问题的最终答案:
All elements above deal with Primary Keys of relations but they all are Natural Keys - so we can leave them as is or replace with Surrogate Keys.
在概念和逻辑练习中,我们只处理逻辑键。代孕等物理概念是非法的。在逻辑练习中,用物理生物替换逻辑键被拒绝。使用您拥有的密钥,这些密钥来自数据,而且很自然。
不是 "Replacement"
还有一点。术语 "replacement" 不正确。代理永远不会替代或替代自然密钥。
自然键提供的众多品质之一是行唯一性,关系模型也需要这一点,不允许重复行。
由于代理项不是行的键(它是指向记录的物理指针),因此它无法提供所需的行唯一性。如果你不完全明白我在说什么,请阅读 this Answer,从顶部到 False Teachers。测试给定的代码练习。
因此,在物理建模阶段,即使考虑了代理项,也始终是附加列和索引。它不是自然关系键的替代品。
并且相反,如果代理 是 作为替换实现的,结果是重复行,non-relational 文件,而不是关系 table.
案例一
Key Attribute is a name - so it must be of type CHAR or VARCHAR. Generally names become Key Attributes.
是的。
通常它们是代码(用户确实使用代码)。 Codes 通常会跳到你面前(你在 One More Update 中有一个很好的例子)。 { D |右 | B } 也一样 { < | ^ | > }。这当然是接近逻辑模型阶段的末尾,此时模型为 stable,并且正在完成 Keys 并对其进行优化。对于早于此的任何阶段,宽自然键都有效。
我们的想法是让它有意义。
键有意义(代理没有意义)。关系键的一个特性是,无论键作为外键迁移到哪里,它的含义都会被传递。
并且根据您的示例,无论在何处使用。包括程序代码。写作:
IF CrewType = "Backup" -- meaningful but fixes a value IF CrewType = 1 -- meaningless
完全错误。因为(a)那不是真正的键,并且(b)用户很可能将该数据的值从 Backup
更改为 Reserve
,等等。永远不要编写寻址数据值的代码,a描述符。所以事实是,Backup
是Key的投影,exposition,代码是Key。解析为 CrewType.Name,密钥为 CrewTypeCode。
IF CrewTypeCode = "B" -- Key, meaningful, not fixed
当我们使用 Keys 时,请注意:
在关系模型中,我们有主键、备用键和外键(迁移的主键)。
我们没有"candidate keys",RM中没有定义这样的东西。是RM以外制造的东西。因此是non-relational。
更糟糕的是,它们被实施代理的人用作 "primary keys" a.
一种身体上的考虑 b,但应该在整个练习中理解和应用。当数据被理解和已知时,列将是固定长度的。当它们未知时,它们可能是可变的。对于键,考虑到它们将被索引,至少在主端,它们永远不应该是可变的,因为这需要在每次访问时解包。
一个。使用 SQL 关键字 PRIMARY KEY
不会神奇地将代理项转换为 PK。如果一个遵循RM,一个(a)确定可能的Keys(无代理),然后(b)选择一个作为Primary,这(c)意味着选举结束,因此(d) 提名的候选人不能再称为 "candidates",事件已成为历史,因此 (e) 其余的 non-primary 密钥是备用密钥。
"Candidate key"是拒绝符合RM而提名一个PK,因此,就其本身而言,它是non-relational.除了他们有一个替代品 "primary key",这是第二个 non-relational 项。
b.对于那些 non-technical 认为没有技术知识和远见,根本没有物理考虑的人,应该在逻辑上进行评估,没关系,在物理上评估他们。由于我不是在这里解决物理问题,所以我只是为 Umbra 做个笔记。
魔术师们凭借自己的魔术,让小兔变成了狮子。科学家不需要它们。
案例二
Two (or more) Identifying Relationships become a Composite Primary Key of a relation (which is made of Foreign Keys).
我认为您的想法是正确的,但对于一般情况,措辞不正确。
该措辞对于具有两个外键的 关联 Table 是正确的。是的,在那种情况下,两个 FK 形成了 PK,这就是行唯一性所需要的。没有比这更好的了。添加记录 ID 是多余的。
对于一般情况,对于任何 table:
一个识别关系 1导致FK(迁移parent PK)成为child中的PK。因此名称 parent 标识 child.
这使得 child 成为 Dependent 1 table,这意味着child 行只能存在于 parent 行的上下文中。这样的 table 形成数据层次结构中的中间节点和叶节点,它们是关系数据库中 table 的大部分。
如果行可以独立存在,则table是独立1。这样的 table 构成了每个数据层次结构的顶部,在关系数据库中很少见。
A Non-identifying关系 1是FK(迁移parent PK), 不用于形成 child PK.
复合或复合键只是由不止一列组成,它们是关系数据库中的标准票价。除了每个数据层次结构的顶部外,每个 table 都有一个复合键。如果没有,则数据库不是关系型的。
请仔细阅读我的IDEF1X Introduction
1. "theoreticians" 不区分 Identifying 与 Non-identifying,或 Dependent 与 Independent:他们所有的文件都是 Independent;记录指针之间的所有 "relationships" 都是 Non-identifying。它是对 1970 年代之前的 ISAM 记录归档系统的倒退,缺乏关系完整性、功能和速度。这就是他们所了解的,这就是他们所能教导的。欺诈性地标记为 "relational".
案例三
Identifying Relationship(s) with Weak Key Attribute(s) also become a Composite Primary Key.
与 "key" 有或没有关系的术语 "weak" 未在 关系模型 中定义。这是"theoreticians"的小说。所以我无法回答这个问题。
我确实注意到一些 "theoretical" 论文将 strong Keys(正常的英文单词,描述 Key 之前已经建立的事实)呈现为 "weak",并且weak "keys"(正常的英文单词,描述"key"之前没有成立的事实)为"strong"。这就是精神分裂症的本质。
因此,我怀疑这是他们试图将科学与 non-science 混淆并破坏 关系模型 的一部分.在过去,当这样的人被关起来时,人类是健康的。现在他们在大学里写书和教书。
案例4
Associative entities usually have two or more Identifying Relationships
是的。两个是正确的。
如果你有两个以上,那就是没有完全归一化。 Codd 给出了一个明确的规范化方法,这样就会有两个(或更多)关联实体,每个实体都有两个完全识别的关系。
- "...因此,所有 n-ary(多于两个)关系...可以...而且应该解析为二元(两个)关系。"
(为此上下文改写)
so they are to be Junction Relations (Junction Tables).
没有。 "Junction" 关系和 "junction" table 未在 关系模型 中定义,因此它们是 non-relational。
逻辑中的关联实体在物理中变为关联 Table。
回答太长
答案的完成超出了 SO 答案的限制。因此,我将答案放在一个文档中,并提供了 link。在这一点上拆分答案被证明是一种罪过,因此文档包含完整的答案,具有一致的格式等:
要从这一点继续(即上面的 SO 答复文本),只需向下滚动到 案例 4 标题。
保留上述 SO Answer 文本是有价值的,不仅用于历史目的,还用于文本搜索等。