2

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

这就是我想做的事情。

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或类似的东西会给我用户选择的所有位置选项。我的偏好表将包括宗教、位置、饮食、饮酒习惯等。有没有更好的方法来做到这一点?

4

2 回答 2

2

我非常喜欢首先从领域驱动设计的角度来看待这个问题。这是一个相当深入的主题,但总的来说,您希望对关键概念进行建模并确保您将编写的代码是合理的。这假设您计划以面向对象的方式解决此问题。

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

在实体方面,我首先定义“用户”及其个人属性(“姓名”、“宗教”、“位置”)。

然后,我将仔细研究您计划用来生成“匹配”的每个首选项。您可能会发现很多需要考虑添加到模型中的东西(即“位置”是一组纬度/经度和半径或一组邮政编码)。

我的感觉是,最初在选项和偏好方面变得通用会适得其反。您至少需要定义其中的一些,看看有什么共同点,并将共同点提升到父类或接口中。

对于数据持久性,请在代码中保持职责分离。您的实体不应该为自救负责。您应该创建其他对象,将您的实体映射到您选择的任何数据库(文档,任何)结构。这将使您可以更改底层持久层,而不会直接影响站点的功能。说 PHP 的一个例子是Doctrine ORM

最后,熟悉单元测试。您没有提及您的实现语言,因此这里列出了您用作参考的单元测试框架。

我知道这并不能直接回答您的问题,因此可以为您提供更多有关主题的答案;

  • 保持数据库规范化(除非您需要非规范化以提高性能)
  • 使用外键来维护参照完整性
  • 在需要时重构您的数据库结构
于 2012-12-31T03:28:22.767 回答
2

查看您的解释,我建议拆分两个实体,即:偏好和位置。如果您将位置包含在首选项表中,您可能需要标记列,或者此首选项是否是位置。我假设系统应该找到具有相同偏好的匹配项,即爱好、宗教居住在理想的地区,没有相同的偏好居住在某个地区。因此,我建议稍微更改架构。

在此处输入图像描述

然后,您可以简单地查询另一个用户偏爱的某个特定位置中的匹配项以及他选择的偏好(如果我们正在寻找 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)。

于 2012-12-31T04:46:04.980 回答