建议:设计典型的用户组关系数据库表时的困境

时间:2014-01-21 09:30:30

标签: sql sql-server database

我在最近的一个项目中遇到了这个非常典型的用户组关系问题。基本上,系统中有几个用户和组,每个用户可以加入他喜欢的任何组。目前,我设计数据库表如下

设计1

[user_table] ID,姓名,电子邮件

[group_table] id,name,intro

[relation_table] uid,gid

当实现“列出给定组的所有用户”函数时,它至少涉及两个表:relation_table和user_table。要尽可能使用一个数据库连接,我使用JOIN子句。但问题是:我应该把这个函数放在哪里,userDAO或relationDAO?由于此函数涉及两个表,因此它似乎违反了“每个表的一个DAO”规则。

但我有另一个想法

设计2

[user_group_table] uid,uname,uemail,gid,gname,gintro

所以这里只有一个组合表,但我可以看到,当更多用户加入组时,用户信息和组信息会重复。如果某个列(如gintro:group introduction)是一个长文本列,它是否会显着增加db大小?

此外,如果某些列是可更新的,更新一个拥有数千个用户的组的效率是否会非常低效?

你们怎么解决这类问题?真的需要一些建议!


后续问题:

假设我在这里使用原始JDBC并且必须将原始数据解析为DAO中的对象。所以我至少应该在userDAO中将“用户行写入用户对象”代码一次。现在,如果我遵循第一个设计,我将不得不再次在relationDAO中编写它,因为我必须使用列别名来区分两个“名称”列。这两段代码中的大多数都是相同的,但我必须将它们保存在两个地方。看起来有点不受我的影响。


第二个跟进问题:

现在,如果我在用户表上有一个搜索功能,它在名称和电子邮件上一起使用SQL LIKE子句(例如:SELECT * FROM user_table u WHERE u.name LIKE“frog%”或u.email LIKE“青蛙%“)和我的”邪恶“PM请求我另一个“搜索来自给定组的用户”函数,其行为与原始搜索函数相同,只是返回给定组中的用户。所以在这里,我面临一个涉及两个表的函数,其部分逻辑(搜索相关子句)在userDAO中。我应该在哪里放置这个功能?

1 个答案:

答案 0 :(得分:2)

您的第一个设计比第二个设计具有更高的标准化。

“列出群组中的所有用户”和“列出用户的所有群组”都应转到 relationDAO

这是因为你只需要:

public IEnumerable<User> getUsersForGroup(int groupId);

public IEnumerable<Group> getGroupsForUser(int userId);

  

每个表一个DAO

规则不是指这种情况,而是指您不应该使用两个用户DAO这一事实。

总而言之,我会选择第一个设计,因为它在关系数据库设计的上下文中更有意义,我会将提到的查询放在关系DAO中