多个用户首选项的数据库设计?

时间:2012-12-31 02:14:19

标签: mysql database postgresql database-design

我正在为约会网站设计一个数据库,要求用户选择合作伙伴偏好,从而推动匹配过程。基本上,我想要的是用户能够为每个首选项设置单个或多个选项。例如,合作伙伴位置可以是仅纽约,纽约,波士顿,迈阿密,洛杉矶等。我想知道我想到的想法是否是首选的做事方式。

这就是我在想的事情。

Users Table |    User_Options Table    |    Options Table    | Preferences Table
            |                          |                     |           
ID | Name   | ID | User_id | Option_ID | ID | Name | Pref_id | ID | Name 
1. | John   | 1. |  1.     |   1.      | 1. |  NY  |   1     | 1. | Location
            |                          |                     |

这种方式每个都有很多选项,每个选项都有很多用户。我已将选项表链接到首选项,以便我可以根据首选项类别调用用户。我希望user.location或这些行中的某些内容会为我提供用户选择的所有位置选项。我的偏好表将包括宗教,地点,饮食,饮酒习惯等。有更好的方法吗?

2 个答案:

答案 0 :(得分:2)

我首先从Domain Driven Design的角度来看待这个问题。这是一个相当深入的主题,但总的来说,您希望对关键概念进行建模,并确保您要编写的代码是合理的。这假设您计划以面向对象的方式处理此问题。

如果您根据具有状态和行为的对象来考虑您的项目,您(希望)最终会得到更强大的代码,可以更好地处理更改。

就实体而言,我首先要定义“用户”及其个人属性(“名称”,“宗教”,“位置”)。

然后,我会仔细查看您计划用于生成“匹配”的每个首选项。您可能会发现很多东西都缺少,您可以考虑添加到模型中(即“位置”是设置纬度/长度和半径或一组邮政编码)。

我的感觉是,最初在选项和偏好方面的通用性会适得其反。您需要至少定义其中的一小部分并查看常见内容并将共性提升为父类或接口。

对于数据持久性,请在代码中保持职责分离。您的实体不应该自行保存。您应该创建其他对象,将您的实体映射到您选择的任何数据库(文档,任何)结构。这将允许您更改基础持久层,而不会直接影响您网站的功能。举例来说PHP就是Doctrine ORM

最后,熟悉单元测试。你没有提到你的实现语言,所以这里是你用作参考的list of unit test frameworks

我知道这并没有直接回答你的问题,所以要给你一个更多的主题答案;

  • 保持数据库规范化(除非 需要进行非规范化以提高性能)
  • 使用外键来维护引用完整性
  • 根据需要重构您的数据库结构

答案 1 :(得分:2)

看看你的解释,我建议拆分两个实体,即:偏好和位置。如果您将在首选项表中包含位置,则您可能需要标记的标记列或此首选项是位置或不是。我假设系统应该找到具有相同偏好的匹配,即爱好,宗教 AND 生活在理想的区域,没有相同的偏好 OR 生活在某些区域。因此我建议略微改变架构。

enter image description here

然后,您可以简单地查询其他用户偏好的某些特定位置的匹配以及他选择的偏好(如果我们正在寻找用户的匹配,其中user_id 1跟随他/她喜欢的位置和偏好):

select r.user_id
from
(select uu.user_id from users u
right join user_location ul using (user_id)
right join users uu on uu.location_id = ul.location_id
where u.user_id = 1) r
inner join user_preference up on up.user_id = r.user_id
inner join user_preference up1 on up1.preference_id = up.preference_id and 
       up1.user_id = 1
group by r.user_id;

另一个问题:如果您在考试中使用像User_Options这样的联结表 - 则无需创建人工密钥。在这种情况下,复合主键(user_id和option_id)将更加合理。 (查看我的示例中的2个联结表 - user_locations和user_preferences)。