涉及多个表的一对一关系
One to one relationship involving multiple tables
说,
我有 3 个 table。
User
其中包含有关用户的基本信息。
SectionA
其中包含有关用户的更多信息。
SectionB
其中还包含有关用户的更多信息。
每个用户只能有一个SectionA
和SectionB
数据。
我的想法是创建这样的 table 设计:
id name section_a_id section_b_id
1 matt 1 1
问题是,section_a_id
和 section_b_id
不能自动递增,因为它们不是主键。
所以我尝试了一种不同的方法,并决定 User
中的 id
主键应该是引用 section_a_id
和 section_b_id` 的外键。但我无法这样做,因为 mysql 只允许引用一个 table。
那么我应该如何处理这种情况?
您似乎有:
- 1-n User-SectionA 关系
- 1-n User-SectionB 关系
所以外键必须在 SectionA 和 SectionB tables 中并且它们必须是用户 table 主键。
There can only be one SectionA and SectionB data for each user.
这引出了一个问题,即为什么要将数据存储在不同的 table 中。这有时是一件好事——不同的用户可能在不同的 tables.
一个解决方案是让 SectionA
和 SectionB
的主键成为对 UserId
的外部引用。是的,这是允许的。
另一个解决方案是在 users
table 中添加 sectionA_id
和 sectionB_id
。然后你可以在每个引用的 tables.
中有一个自动递增的 id
如果是一对一的关系,将三个 table 组合成一个大的 table 总是更容易,第 table 部分的列可以为空。
我可以看到这种方法的一些优点:
- 更轻松的插入、更新和删除操作。
- 当要使用的连接较少时,数据检索速度更快。
- 更少的索引 space,因为您正在为一个 table 而不是三个 table 索引主键。
1:1
的罕见用途
- 你的栏目真的太多了;
- table 很大,您不想更改 table 以添加更多内容;
- 其中一个 table 大部分是可选的,您使用
LEFT JOIN
获取空值。
纠正一些AUTO_INCREMENT
误解
- 该列不必是
PRIMARY KEY
,甚至 UNIQUE
;它只需要是某个索引中的第一列。
- 您根本 不必 有一个
AUTO_INCREMENT
列。通常最好使用 "natural" PK——一些本质上是 UNIQUE
. 的列(或列的组合)
构建一对 1:1 table 时,这是 一个 方法
- 构建第一个 table,
PRIMARY KEY
即 AUTO_INCREMENT
。
- 使用与另一个相同的
PRIMARY KEY
构建第二个 table,但不是 AUTO_INCREMENT
。
- 插入行时,使用
LAST_INSERT_ID()
获取id。
- 使用该值明确指定第二个 ID table。
说,
我有 3 个 table。
User
其中包含有关用户的基本信息。
SectionA
其中包含有关用户的更多信息。
SectionB
其中还包含有关用户的更多信息。
每个用户只能有一个SectionA
和SectionB
数据。
我的想法是创建这样的 table 设计:
id name section_a_id section_b_id
1 matt 1 1
问题是,section_a_id
和 section_b_id
不能自动递增,因为它们不是主键。
所以我尝试了一种不同的方法,并决定 User
中的 id
主键应该是引用 section_a_id
和 section_b_id` 的外键。但我无法这样做,因为 mysql 只允许引用一个 table。
那么我应该如何处理这种情况?
您似乎有:
- 1-n User-SectionA 关系
- 1-n User-SectionB 关系
所以外键必须在 SectionA 和 SectionB tables 中并且它们必须是用户 table 主键。
There can only be one SectionA and SectionB data for each user.
这引出了一个问题,即为什么要将数据存储在不同的 table 中。这有时是一件好事——不同的用户可能在不同的 tables.
一个解决方案是让 SectionA
和 SectionB
的主键成为对 UserId
的外部引用。是的,这是允许的。
另一个解决方案是在 users
table 中添加 sectionA_id
和 sectionB_id
。然后你可以在每个引用的 tables.
如果是一对一的关系,将三个 table 组合成一个大的 table 总是更容易,第 table 部分的列可以为空。
我可以看到这种方法的一些优点:
- 更轻松的插入、更新和删除操作。
- 当要使用的连接较少时,数据检索速度更快。
- 更少的索引 space,因为您正在为一个 table 而不是三个 table 索引主键。
1:1
的罕见用途- 你的栏目真的太多了;
- table 很大,您不想更改 table 以添加更多内容;
- 其中一个 table 大部分是可选的,您使用
LEFT JOIN
获取空值。
纠正一些AUTO_INCREMENT
误解
- 该列不必是
PRIMARY KEY
,甚至UNIQUE
;它只需要是某个索引中的第一列。 - 您根本 不必 有一个
AUTO_INCREMENT
列。通常最好使用 "natural" PK——一些本质上是UNIQUE
. 的列(或列的组合)
构建一对 1:1 table 时,这是 一个 方法
- 构建第一个 table,
PRIMARY KEY
即AUTO_INCREMENT
。 - 使用与另一个相同的
PRIMARY KEY
构建第二个 table,但不是AUTO_INCREMENT
。 - 插入行时,使用
LAST_INSERT_ID()
获取id。 - 使用该值明确指定第二个 ID table。