将数据存储在链接表中

时间:2011-01-04 14:43:35

标签: mysql database-design

Supoose我有以下内容:


tbl_options
===========
id    name
1     experience
2     languages
3     hourly_rate


tbl_option_attributes
=====================
id    option_id    name          value
1     1            beginner      1
2     1            advanced      2
3     2            english       1
4     2            french        2
5     2            spanish       3
6     3            £10 p/h       10
7     3            £20 p/h       20


tbl_user_options
================
user_id    option_id    value
1          1            2
1          2            1
1          2            2
1          2            3
1          3            20

在上面的示例中,tbl_user_options存储用户的选项数据。我们可以为一些选项存储多个条目。

现在我希望扩展这一点,即对于“语言”,我希望用户能够指定他们对语言(基本/中级/高级)的熟练程度。还有其他字段将具有扩展属性。

所以我的问题是,这些扩展属性可以存储在同一个表中(tbl_user_options)还是需要创建更多表?显然,如果我输入“language_proficiency”字段,它将不适用于其他字段。但是这样我只有一个用户选项表来管理。你觉得怎么样?

编辑:这就是我的建议


tbl_user_options
================
user_id    option_id    value     lang_prof
1          1            2         null
1          2            1         2
1          2            2         3
1          2            3         3
1          3            20        null

3 个答案:

答案 0 :(得分:1)

我的直觉是将用户/语言/熟练关系分成自己的表格。即使您将其与其他选项保存在同一个表中,您也需要编写特殊代码来处理语言案例,因此您也可以使用新的表结构。

答案 1 :(得分:0)

除非您的数据模型不断变化,否则我宁愿使用tbl_languagestabl_user_languages表来存储这些类型的数据:

tbl_languages
================
lang_id    name
1          English
2          French
3          Spanish

tbl_user_languages
================
user_id    lang_id      proficiency  hourly_rate
1          1            1            20
1          2            2            10
2          2            1            15
2          2            3            20
3          3            2            10

设计“太通用”的系统是关系SQL数据库的Turing tarpit陷阱。基于文档的数据库更适合任意键值存储。

除了某些优化之外,您的数据库模型应尽可能与您的域模型匹配,以最大限度地减少对象 - 关系阻抗不匹配。

此设计让您只需两个内部联接即可显示用户语言熟练度和小时费率的合理表格:

SELECT
    ul.user_id,
    u.name,
    l.name,
    ul.proficiency,
    ul.hourly_rate
FROM tbl_user_languages ul
INNER JOIN tbl_languages l
    ON l.lang_id = ul.lang_id
INNER JOIN tbl_users u
    ON u.user_id = ul.user_id
ORDER BY
    l.name, u.hour

您可以选择将语言熟练程度列表拆分为tbl_profiencies表格,其中1 == Beginner2 == Advanced3 == Expert并将其加入tbl_user_languages

答案 2 :(得分:-1)

我认为将“语言”作为一种选择是错误的。在阅读你的文字时,在我看来,英语是一个选项,它可能有一个来自option_attributes的属性。