我必须将此信息保存在数据库中
人 -> 与 -> 人结婚
我应该在哪里保存该信息?我应该在这里应用什么正确的设计模式?
谢谢!
如果只能与一个人结婚:1:1
-------------
- Person -
-------------
id (key)
maried_to_id (foreign key)
如果您可以与多个人结婚或想要记录以前的婚姻,n:n
-------------
- Person -
-------------
person_id (key)
-------------
- Mariage -
-------------
first_person_id (foreign key)
second_person_id (foreign key)
start_date
end_date
(first_person_id + secondary_person_id + date 形成婚姻的唯一键。您可以省略日期,但不会跟踪再婚)
这是您可以使用的假设模式。所有的人都在一张表中,每个人都有一个唯一的id。婚姻位于关系表中,带有外键。
PERSONS
- ID - INTEGER, PK
- FIRSTNAME - VARCHAR(20)
- LASTNAME - VARCHAR(20)
- SEX - CHAR(1)
- ... any other fields
MARRIAGES
- PERSON1_ID - INTEGER, FK
- PERSON2_ID - INTEGER, FK
- MARRIAGE_DATE - DATE
- ANULLMENT_DATE - DATE
- ... any other fields
对于教学模式设计来说,这是一个很好的问题。看似简单的问题很容易变得相当复杂:
例如,如何处理:
- 两人以上的婚姻
- 不同类型的婚姻(合法、宗教、其他)
- 同时结婚
- 重复婚姻
- 离婚
- 自婚(嘿,这发生在《欢乐合唱团》上!)
如果有技巧的话,那就是仔细思考你想要建模的所有排列。只有这样你才能真正继续建模。
我会推荐以下结构 假设表名称是 Person。
......
无需创建外键关系。
这听起来像是一个简单查找表的用途 - 重要的部分是有两个字段,一个是 Person1 的 ID 字段的外键,另一个是 Person2 的 ID 字段的外键。有关婚姻的任何详细信息(日期、是否仍然有效等)也将存储在此表中。
这将有利于人们有多段婚姻、一夫多妻关系等。如果您想要一个简单的 1:1 关系,您可以只在人员字段中包含对配偶的外键引用,但这会大大降低灵活性。
您可以使用“个人”表上的“配偶”列来完成此操作,该列可以为空(对于未婚者的情况)。
如果已婚,则保存对方的 ID,就像外键一样。
更好的解决方案是一个单独的“婚姻”表,至少有三列:
MarriageId
Person1Id
Person2Id
...
人员 ID 是“人员”表中的外键,您应该使 MarriageId、Person1Id 和 Person2Id 的组合唯一,以避免添加人员交换的行。
不过应该指出的是,这两个模型都非常基本,并且对一段婚姻中可以有多少人做出了假设;)
有婚姻模式。 您需要一个事件(例如,婚姻、审判、飞行、比赛等)和参与者。 对于事件,事件表至少包含 start_date(可能是事件的主键)并且通常包含 end_date。 如果是婚姻,我们创建一个带有属性的婚姻表:
我们可以添加属性。例如,举行仪式的地方。
参与者来自具有属性的人员表:
有一个 event_vs_participant 表将事件和参与者关联起来。 该表有一个 role_code 属性。对于婚姻,您将获得伴侣、司仪、证人等角色。对于审判,您将获得法官、证人、律师等角色。对于航班,您将获得乘客、机组人员等角色。对于比赛你可以扮演竞争者、裁判员、观众等角色。 如果是婚姻,我们创建一个包含以下属性的 wedding_vs_participant 表:
该表有外键,其中包含表婚姻、人员和角色。
您应该避免创建带有属性的表:
该表包含人员列表,未达到第一范式。