多对多数据库设计问题

时间:2010-02-05 23:20:32

标签: sql mysql database database-design

假设您有以下多对多表关系:

user
-----
id
first_name
last_name

user_prefs
----------------
id
preference_name

user2user_prefs
-------------
id
user_id
user_pref_id

但是说你有“主页”的用户偏好并且需要某处存储实际的主页网址。那会怎样?

我无法在user_prefs中添加值,因为相同的值将适用于具有该映射的每个人。

我可以将它放在user2user_prefs中,如下所示:

user2user_prefs
-------------
id
user_id
user_pref_id
value

但这是正常化方面的最佳方式吗?对于我这样做的方式感觉不太正确(一方面,我不能在新的“值”上使用ENUM,因为它必须包含所有首选项的所有值)。有什么想法吗?

谢谢! Stabby L

4 个答案:

答案 0 :(得分:3)

您必须查看功能依赖项。该值不依赖于用户,它不依赖于userpref,但它依赖于两者。这意味着您需要按照建议将其放在user2user_prefs选项卡中。

如果需要使用枚举,则value属性可以在另一个表中查找值。

答案 1 :(得分:1)

  

我无法在user_prefs中添加值   因为那样的价值会相同   适用于拥有该权限的每个人   映射。

你正常化了。主页在user_prefs中没问题。

事实上,如果我是你,我只会使用一张桌子:

user
-----
id
first_name
last_name
homepage
<other settings>

外键关系,特别是多对多关系,复杂性成本很高。软件开发人员的工作就是控制复杂性。

答案 2 :(得分:1)

在我看来,特定类型的价值实际上并不属于许多关系。如果特定属性值特定于每个用户,那么它似乎应该是一个单独的表。它“感觉”就像从user到另一个具有每个用户独有的首选项的表的1-many关系。

编辑:对于1到多个表:

user_specific_prefs
------
id
user_id
pref_name (or possibly pref_id that indicates the type)
pref_value (store www.myhome.com for example)

user_id只是返回特定用户的外键。这基本上(在逻辑意义上)向用户表添加其他列。但正如Andomar指出的那样,它确实增加了复杂性。但如果您有大量的偏好,那么可能会很好。另一方面,我见过有数百列的表。我并不是说这很好(而且我没有创造它们),但他们完成了工作并且易于使用。

答案 3 :(得分:0)

你非常接近。

<编辑:我以前认为很棒的答案并不那么精彩。]

编辑表:

users
-----
id
first_name
last_name
preferences

首选项字段将包含特定用户选项的序列化对象或数组。 在PHP中:

if ( is_array( $options ) || is_object( $options ) )
       serialize( $options );

Serialize Manual