Mysql 用于单个表之间的一对一的SQL

Mysql 用于单个表之间的一对一的SQL,mysql,sql,Mysql,Sql,我想知道从一个(我的)sql表中精确反映两行之间关系的最佳方法是什么 举例来说,我们有: table Person { id, name } 如果我想反映一个人可以一夫一妻制结婚(至少在自由国家是这样),那么在人身上使用外键是否更好: table Person { id, name, spouse_id(FK(Person.id)) } 然后创建结婚和离婚人员的存储过程(确保婚姻的相互注册或撤销+触发以处理删除事件)。。 或使用映射表: table Marriage { spouse_a

我想知道从一个(我的)sql表中精确反映两行之间关系的最佳方法是什么

举例来说,我们有:

table Person { id, name }
如果我想反映一个人可以一夫一妻制结婚(至少在自由国家是这样),那么在人身上使用外键是否更好:

table Person { id, name, spouse_id(FK(Person.id)) }
然后创建结婚和离婚人员的存储过程(确保婚姻的相互注册或撤销+触发以处理删除事件)。。 或使用映射表:

table Marriage { 
 spouse_a(FK(Person.id)), 
 spouse_b(FK,Person.id) + constraint(NOT IN spouse_a))
}
这样,离婚(delete)将只是删除查询,而不需要级联触发器,结婚也不需要存储过程。 制约因素是防止一夫多妻制/多婚制

我想第二种选择更可取?最好的方法是什么? 我需要能够时断时续地更新此关系,因此它必须是可管理的

编辑: 感谢您的回复-实际上,该应用程序是网络中的物理点对点接口,实际上是1:1的关系(一夫一妻制婚姻),政府、趋势等的变化不会改变这一点:)
我将使用一个单独的表和a&B,检查a为了确保一夫一妻制,您只需要确保配偶是唯一的。因此,这几乎满足了您的需求:

create table marriage (
    spouse_a int not null unique,
    spouse_b int not null unique
);
唯一的问题是,给定的配偶可以在任一表中。通常通过检查约束来处理此问题:

check (spouse_a < spouse_b)
检查(配偶a<配偶b)
瞧!关系的唯一性

不幸的是,MySQL不支持检查约束。因此,您可以使用触发器或在应用程序层实现此功能。

选项#1-从结构上添加关系

您可以为两个人之间的每一种可能的关系添加一个额外的表。但是,当有人要求一个新的关系时,您忘记了在结构上添加,您需要添加一个新表

然后,一次会有三个人的关系。然后是四个。然后是可变大小的关系。你说吧

选项#2-将关系建模为表格

为了使其简单易懂(好吧……永远不可能),您可以将这些关系建模到一个新表中。此表可以具有多个属性,例如
大小
,您还可以对其建模限制。例如,如果你愿意,你可以决定让一个人成为“邪教领袖”


这个选项需要更多的努力来设计,但会抵制更多你以前从未想过的来自客户的选项和想法。

你为什么要阻止一夫多妻制?MySQL实现的唯一约束类型是外键。您不能自动执行
约束(不在配偶a中)
,您必须使用检查它的触发器。交叉表是正确的方法,但我会使其更通用,并将其命名为“person\u relationships”,带有关系类型和日期有效性。这样,如果“spoy”改变了,你可以把它定下来,关系也变得更加开放。您唯一需要更多的时间是如果每个person\u id在表中都有一个特定的角色,在这种情况下,将有person\u one\u类型、person\u two\u类型(例如丈夫/妻子)。这样,孩子们也可以用(父亲/儿子,母亲/儿子)来处理。约束是否应该是
约束uq1唯一的(配偶a,配偶b)
?或者,您可以切换到支持
检查
约束的MariaDB 10.2.1。@MPaler。相反。关键是每一位配偶都是独一无二的,不能与任何其他人建立关系。