在Meetup.com中,当您加入聚会小组时,通常需要为该特定小组填写个人资料。例如,如果您加入电影聚会小组,则可能需要列出您喜欢的电影类型等。
我正在构建一个类似的应用程序,其中用户可以加入各个组并为每个组完成不同的个人资料详细信息。假设有两种可能性:
对此类数据进行建模的最佳方法是什么?
更详细的例子:
“电影观众”组要求其成员指定以下内容:
“极限运动”组要求其成员指定以下内容:
最重要的是,每个小组可能需要加入其小组的成员提供不同的详细信息。理想情况下,我希望任何人创建一个组(ala MeetUp.com)。但是,我还需要能够很好地查询成员(例如找到所有年龄在25到30岁之间的女性电影观众)。
答案 0 :(得分:7)
对于这样的事情....你想要最大规范化,所以你不会在任何地方重复数据。因为您的用户定义的表可能包含相同类型的记录,所以我认为您可能需要超过3NF。
我的建议是这样 - 爆炸你的桌子,以便你有一些接近6NF的EAV,这样用户必须回答的每个问题都有自己的表格。然后,您的用户创建的表将引用您的一个问题表。这避免了重复数据问题。 (例如,您不希望“MovieGoers”组中的条目名为“John Brown”,而“极限运动”组中的条目名称为“Johnny B.”,对于同一用户;您也不要我希望他的“你最喜欢的颜色”的答案是一组中的“蓝色”和另一组中的“红色”。任何可以跨组的数据,如常见问题,都会以这种形式标准化。)
这样做的主要缺点是你最终会得到很多表,而你可能想为统计查询创建视图。但是,就纯数据完整性而言,这将很有效。
请注意,如果你真的想要,你可能只能将公共字段分解出去。常见字段的示例包括姓名,位置,性别等;你也可以对常见的问题做同样的事情,比如“你最喜欢的颜色是什么”或“你有宠物”或者那种程度的东西。不跨组的特定于组的问题可以存储在该组的单独表中,未爆炸。我不建议这样做,因为它不像纯6NF选项那样灵活,你冒着重复的风险(你如何预先确定哪些问题不是常见的问题?)但如果你真的想要,你可以这样做。
这里有一个关于6NF的好问题:Would like to Understand 6NF with an Example
我希望这有点意义,我希望它有所帮助。如果您有任何疑问,请发表评论。
答案 1 :(得分:6)
实际上,这正是SQL不是正确解决方案的问题。忘记规范化。这正是NoSQL文档存储的工作。每个用户都是一个文档,有一些必要的字段,如id,name,pwd等。每个组都增加了添加一些字段的可能性。唯一字段可以具有名称group-id-prefixed,共享字段(掌握一些更一般的概念)可以使该字段名称免费。
除了用户(和组)之外,您将拥有包含名称,类型,可能值......的字段描述,这对于文档存储也非常有用。
如果您从一开始就使用键值文档存储,那么您可以获得构建数据的自由形式 plus 查询它们(虽然不是通过SQL,但是通过这个或那个NoSQL数据库提供的方式) )。
答案 2 :(得分:1)
首先我要注意,以下结构只是数据库的基础,您需要扩展/缩小它。
DB中有以下实体:
"建模":
**User**
user_id
user_name
**Group**
name
group_id
user_group
user_id (FK)
group_id (FK)
**requirement**:
requirement_id
requirement_name
requirement_type (FK) (means the type: combo, free string, date) - should refers to dictionary)
**template**
template_id
template_name
**template_requirement**
r_id (FK)
t_id (FK)
下一步是为存储限制建模适当的模式,即验证任何模板中任何需求的规则。我们必须将它分开,因为对于不同的组,相同的限制可能不同(例如:"年龄")。您可以使用下表:
**restrictions**
group_id
template_id
requirement_id (should be here as template_id because the same requirement can exists in different templates and any group can consists of many templates)
restriction_type (FK) (points to another dict: value, length, regexp, at_least_one_value_choosed and so on)
所以,正如我所说,这是基础。您可以随意简化此架构(清除表格,组的多个模板)。或者,您可以更方便地添加创建和发布temaplate,要求等的机会。
希望您觉得这个想法很有用
答案 3 :(得分:0)
您可以将此类数据保存为JSON或XML(结构,数据)
用户表
GroupStructure表
GroupData表
答案 4 :(得分:0)
我认为这涵盖了大部分限制因素:
users user_id, user_name, password, birth_date, gender 1, Robert Jones, *****, 2011-11-11, M group group_id, group_name 1, Movie Goers 2, Extreme Sports group_membership user_id, group_id 1, 1 1, 2 group_data group_data_id, group_id, group_data_name 1, 1, Favorite Genres 2, 2, Favorite Activities group_data_value id, group_data_id, group_data_value 1,1,Comedy 2,1,Sci-Fi 3,1,Documentaries 4,2,Extreme Cage Fighting 5,2,Naked Extreme Bike Riding user_group_data user_id, group_id, group_data_id, group_data_value_id 1,1,1,1 1,1,1,2 1,2,2,4 1,2,2,5
答案 5 :(得分:0)
我遇到过类似的问题。我不确定这是否是针对您具体情况的最佳建议,但请考虑一下。
提供一种将数据存储为XML或JSON的方法,或者用于分隔数据的其他格式,但基本上将其存储在没有特定格式的字段中。
提供存储该数据定义的方法
为数据提供查找/索引表。
这是已经表明的技术组合。
基本上,您可以为客户创建一些界面,以便为他们想要保存的内容创建“表单”。此表单将指示他们希望从用户获得哪些信息。它还会指出您要搜索的信息。
将此信息保存到定义表中。
然后使用定义表来描述用于输入数据的用户界面。
输入用户数据后,将数据(如xml或其他数据)保存到具有唯一ID的一个表中。同时,另一个表将作为索引填充
id保存xml数据的位置 字段数据的名称存储在 存储的现场数据的值。 数据定义的id。
现在当搜索开始时,通过名称,值和定义id搜索索引表中的信息并获取存储在表中的xml / json(或其他)数据的id应该没有问题数据表格已存储。
检索后,该数据应该可以转换。
我对这里的细节非常粗略,我希望这足以让你开始。如果您需要任何解释或其他详细信息,请告诉我,我们将很乐意为您提供帮助。
答案 6 :(得分:0)