【发布时间】:2015-01-07 02:03:15
【问题描述】:
背景:我有一个包含父母和孩子姓名的数据库(这是对实际数据的简化,但类比很接近够了)。
任务:数据库必须为每个父母存储儿童姓名的有序列表。 p>
假设:
- 该数据库将包含数百万父母,甚至更多。
- 父母的孩子通常不超过 4 或 5 个,但也必须支持罕见(甚至极端)的情况。
- 孩子的名字(以及顺序)往往会重复很多。所以家长应该参考一些
children_names_list_id,而不是保留真实姓名的副本。 - 孩子的名字以及他们对特定父母的排序是不可变的。
- 新父母的加入将非常频繁。当插入新的父级及其子级列表时,如果数据库中已经存在这样的名称列表,则新的父级应引用现有的列表标识符。
- 应该可以查询关于姓名及其顺序的查询(例如 - 在将孩子命名为“Alice”之后查找所有将孩子命名为“Bob”的父母,或查找所有命名为“Bob”的父母一个孩子“爱丽丝”,然后又生了两个孩子,第三个孩子叫“卡罗尔”等等)
问题:
- 存储此类列表的最佳方式是什么?该解决方案应该是健壮的并支持快速的父插入。
- 家长应如何引用列表?
当前(建议的)解决方案:
我目前的方法是创建一个表,将 children names 映射到 integer name ids(名称很长,整数很短)。
然后将名称列表存储在以下元组中:<list_id> <order> <name_id>,因此列表表将如下所示:
<list_id> <order> <name_id>
1 1 123
1 2 345
1 3 678
2 1 901
3 1 123
3 1 901
示例表包含三个列表:[123,345,678]、[901]、[123,901],它们可能对应于以下内容:["Alice"、"Bob"、"Carol"]、["Dave"]、["爱丽丝”、“戴夫”]
然后,父表将有一个引用 list_id 列的 children_list_id 列。
这个解决方案似乎很健壮,除了两个问题:
- 我不确定插入是否足够快(查找现有列表是否已经存在似乎可能很慢),但其他方法似乎不太健壮或(更)难以查询。
- 名称列表表的键由
list_id和order列组成;父表必须仅引用应该是外键的list_id,但由于list_id本身不是列表表中的键,因此需要一个额外的列表表,其中list_id是键.这似乎很麻烦。
替代解决方案:
列表表将在列中存储隐式排序:
<list_id> <name_1> <name_2> <name_3> <name_4> ... <name_100>
1 111 222 333 null
2 444 null
3 555 111 null
在此表中,list_id 将是主键。
parents 表会保留list_id 作为外键。
这个解决方案不太健壮(我要创建多少列?10?20?50?),但插入更快。由于list_id 是一个键,因此不需要额外的表。然而,一个可能的缺点是某些查询变得更加复杂,因为它们必须引用多个列。
谢谢!
【问题讨论】:
标签: mysql sql sql-server database relational-database