我目前有一个用户表,现在想要为特定用户添加其他与用户相关的信息。接受此信息的表单包含语言和操作系统等字段,每个字段都包含复选框的选项列表。
例如:
已知语言: 复选框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作为语言对于每个不同的用户。
是否有更好的方法来组织架构?
答案 0 :(得分: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
表是唯一的多对多链接表。
但要小心这个设计。绝对是灵活的。但是当您使用此表结构作为实际的域模型时,您会遇到像“查找”这样的术语成为业务术语的情况,而情况可能并非如此。 “语言”和“操作系统”是实际的模型。我建议使用Views或者Stored Procedures从代码中抽象出这个结构。因此,代码将从语言视图或过程中提取语言,而不是直接从Lookup
表中提取。