多个复选框的数据库模式

时间:2012-05-22 22:29:46

标签: database checkbox schema design-decisions

我目前有一个用户表,现在想要为特定用户添加其他与用户相关的信息。接受此信息的表单包含语言操作系统等字段,每个字段都包含复选框的选项列表。

例如:

已知语言:         复选框PHP,         Java中,         红宝石

操作系统知识:         视窗,         Linux中,         MAC

目前我的数据库表如下所示:

USER
----------------------------------------
|  ID  |  Name      |  
-----------------------
|   1  |    John    |    
-----------------------
|   2  |    Alice    |    
-----------------------

LANGUAGES
----------------------------------------
|  ID  | User_ID(FK)     | lang-name  | 
----------------------------------------
|   1  |    1            |   PHP      |
----------------------------------------
|   1  |    2            |   Java     |
----------------------------------------

OS
----------------------------------------
|  ID  | User_ID(FK)     | os-name  | 
----------------------------------------
|   1  |    1            | Windows  |
----------------------------------------
|   1  |    2            |  Windows |
----------------------------------------

这看起来像一个好的架构吗?还有更多这样的用户相关字段,每个字段都需要有自己的表,并且表中似乎有很多冗余,因为成千上万的用户会知道PHP,因此将有数千行以PHP作为语言对于每个不同的用户。

是否有更好的方法来组织架构?

1 个答案:

答案 0 :(得分:1)

也许您可以使用自己的表在数据库中创建LanguageOS第一类实体,然后使用连接表来获得与User的多对多关系。像这样:

User
---------
ID
Name
etc...

Language
---------
ID
Name

OS
---------
ID
Name

UserLanguage
---------
UserID
LanguageID

UserOS
---------
UserID
OSID

这样,实际的实体(UserLanguageOS)是自包含的,只有对他们有意义的数据,没有污染或与他们关系的关注重复彼此。这些关系包含在他们自己的简单数字表中,这些表本身不是实体,而只是实体之间的多对多链接。

没有数据重复(在您的示例数据中,LanguageOS每个只有三条记录,至少现在是这样),如果ORM和其他框架对它们来说会更友好你需要使用它。

修改:根据您的评论,您可以尝试以下内容:

User
---------
ID
Name
etc...

Lookup
---------
ID
LookupTypeID
Value

LookupType
---------
ID
Value

UserLookup
---------
UserID
LookupID

这为您提供了很大的灵活性。在您的示例数据中,LanguageOS将成为LookupType中的记录。所有语言和操作系统都是Lookup中的值,这些值会链接回各自的LookupType。所以仍然没有重复数据。 UserLookup表是唯一的多对多链接表。

但要小心这个设计。绝对是灵活的。但是当您使用此表结构作为实际的域模型时,您会遇到像“查找”这样的术语成为业务术语的情况,而情况可能并非如此。 “语言”和“操作系统”是实际的模型。我建议使用Views或者Stored Procedures从代码中抽象出这个结构。因此,代码将从语言视图或过程中提取语言,而不是直接从Lookup表中提取。