0

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

例如:

已知语言:复选框 PHP、Java、Ruby

操作系统知识:Windows、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 作为语言对于每个不同的用户。

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

4

1 回答 1

1

也许您可以使用自己的表在数据库Language中创建OS一流的实体,然后使用连接表与User. 像这样的东西:

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

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

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

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

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

这样,实际实体 ( User, Language, OS) 是自包含的,仅包含对它们有意义的数据,不会因为它们彼此之间的关系而受到污染或重复。并且这些关系包含在他们自己的简单数字表中,这些表本身不是实体,而只是实体之间的多对多链接。

没有数据是重复的(在您的示例数据中,Language每个OS只有三个记录,至少目前如此),如果您需要使用一个,它对 ORM 和其他框架会更友好。

编辑:根据您的评论,您可能会尝试这样的事情:

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

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

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

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

这为您提供了很大的灵活性。在您的示例数据中,Language并且OS将是LookupType. 所有语言和操作系统都将是Lookup链接回各自的LookupType. 所以仍然没有重复数据。该UserLookup表是唯一的多对多链接表。

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

于 2012-05-22T22:35:34.637 回答