1

我有一个不常见的数据库设计问题,我不确定如何正确处理。有一个表叫做profile存储网站用户的公开资料信息。但是,每个配置文件都可以属于一个人或一对夫妇,因此我需要一个额外的子表来调用person来存储特定于个人的数据。每个profile实体必须至少有一个但不超过两个person子实体。

模拟这种关系的最佳方式(就“犹太洁食”和/或性能而言)是什么?我应该使用常规的一对多并以编程方式或使用存储过程强制执行孩子的数量吗?或者我应该只在父表中创建两个外键字段并允许null其中一个?也许还有另一种我想不到的方法?

编辑:回应戈登问题的附加信息

  • 一个人只能与一个配置文件相关联,并且不能有一个没有配置文件的人。也许这个名字person让人困惑,因为它可能暗示一个人有个人资料,而实际上是个人资料有个人信息。
  • 在夫妻档案的情况下,两个人都是平等的。由于网站的特殊性,2 的限制永远不会改变,但是应该可以添加或删除一个人(使一个人的个人资料成为一对夫妇的个人资料,反之亦然),但永远不能少于 1 或多于2人。
  • 如果没有个人资料数据,就永远不会提取个人数据,但有时可以在没有个人数据的情况下提取个人资料数据。
4

2 回答 2

4

1)

具有两个字段的解决方案:

  • PRO:允许您精确限制每个配置文件的最小和最大人数。
  • CON:允许没有个人资料的人。
  • 缺点:需要 2 个索引(每个字段 1 个)才能有效获取给定人员的个人资料,占用额外空间并可能减慢 INSERT/UPDATE/DELETE。

2)

但是,如果您愿意在应用程序级别强制执行最小数量,您可能会更好地使用以下内容:

在此处输入图像描述

CHECK(PERSON_NO = 1 OR PERSON_NO = 2)

特征:

  • CON:允许无人员配置文件。
  • PRO:限制每个配置文件的最大人数,但只需修改 CHECK 即可轻松更改。
  • PRO:如果你保持上面的标识关系,它不需要额外的索引并且是集群友好的(相同配置文件的人可以物理上靠近存储,最小化 JOIN 期间的 I/O)。

另一方面,如果您有一个键 PERSON_ID(或类似键),那么 {PROFILE_ID, PERSON_NO} 上的附加索引对于有效地对这些字段执行键约束也是必要的。

3)

从理论上讲,您甚至可以将这两种方法结合起来,避免使用无个人资料和无个人资料:

在此处输入图像描述

(PERSON1_ID 不能为 NULL,PERSON2_ID 可以为 NULL)

但是,这会导致循环引用,需要解决延迟约束,遗憾的是 MySQL 不支持。

4)

最后,您可以采用蛮力方法,简单地将两个人的字段放在配置文件表中(并使这些集合中的一个不能为 NULL,而另一个不能为 NULL)。


在所有这些可能性中,我可能会选择 2)。

于 2012-07-23T13:53:38.087 回答
1

正如您在问题中提到的那样,您基本上有两个选择。您可以在表中存储两个字段。或者,您可以拥有第二个包含映射信息的表。

这里有一些额外的问题可以帮助您回答问题:

  • 一个人可以拥有自己的个人资料和作为夫妻一部分的个人资料吗?
  • 个人资料上的两个人是“平等”还是一个是“主人”而另一个是“替补”?
  • 当您获取个人资料信息时,您会始终在个人资料中包含有关所有人的信息吗?
  • 你可以有没有个人资料的人吗?

在这种情况下,我只是偷偷地怀疑“2”的限制将来可能会改变。这建议将映射存储在单独的表中,因为通过添加字段来增加“2”在修改现有代码方面是一个问题。换句话说,创建一个单独的表 person-profile,将人员映射到配置文件。在 mysql 中,您始终可以使用 GROUP_CONCAT() 收集人员级别的信息。

最好将此类相似字段放在同一张表中的一种情况是,其中一个显然是首选,而另一个是备用。在这种情况下,您正在执行很多“coalesce(, )”类型的逻辑。

于 2012-07-22T14:49:02.733 回答