热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

建议:在设计典型的用户组关系数据库表时遇到的困境-Advice:dilemmaindesigningtypicaluser-group-relationDBtables

Icameacrossthisverytypicaluser-group-relationprobleminoneofmyrecentprojects.Basically,

I came across this very typical user-group-relation problem in one of my recent projects. Basically, there are several users and groups in the system, and each user may join any group he likes. Currently, I design database tables as following

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

Design 1

[user_table] id, name, email

[user_table]id、名称、电子邮件

[group_table] id, name, intro

[group_table]id、名称、介绍

[relation_table] uid, gid

[relation_table]uid、gid

When implementing "list all users of a given group" function, it involves at least two tables: relation_table and user_table. To use one db connection as much as possible, I use a JOIN-clause. But the problem is: where should I put this function, userDAO or relationDAO? Since this function involves both tables, it seems to violate "one DAO for each table" rule one way or another.

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

But I have another idea

但我有另一个想法

Design 2

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

uid, uname, uemail, gid, gname, gintro

So here's only one combined table, but I can see here that user info and group info are duplicated as more users join groups. And if some column (like gintro: group introduction) is a long text column, won't it increase db size dramatically?

这里只有一个合并的表,但是我可以看到随着更多的用户加入组,用户信息和组信息被复制。如果某个列(比如gintro: group introduction)是一个很长的文本列,它不会显著增加db的大小吗?

Moreover, if some columns are updatable, won't it be very low efficient to update a group that has thousands of users in it?

此外,如果某些列是可更新的,那么更新一个拥有数千用户的组的效率不是很低吗?

How would you guys solve this kind of problems? Really need some advice here!

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


A follow-up question:

一个后续的问题:

Assuming I'm using raw JDBC here and have to parse raws into objects in DAOs. So I should at least write "user rows to user objects" code once in userDAO. Now if I follow the first design, I would have to write it one more time in relationDAO since I shall have to use column alias to distinct two "name" columns. Most of these two pieces of code are identical but I have to maintain them in two places. Looks a little unwielding to me.

假设我在这里使用的是原始JDBC,并且必须在DAOs中将raws解析为对象。因此,我至少应该在userDAO中编写一次“用户行到用户对象”代码。现在,如果我遵循第一个设计,我将不得不在relationDAO中再写一次,因为我必须使用列别名来区分两个“name”列。这两段代码中的大部分是相同的,但是我必须在两个地方维护它们。看起来对我来说有点乱。


Second follow-up question:

第二个后续问题:

Now if I have a search function on user table, which uses SQL LIKE-clause on name and email together (sth. like: SELECT * FROM user_table u WHERE u.name LIKE "frog%" OR u.email LIKE "frog%"), and my "evil" P.M. asks me for another "search users from a given group" function that behaves the same as the original search function except that only users from a given group are returned. So here again, I'm facing a function involving two tables and part of its logic (the search related clause) is in userDAO. Where should I place this function?

现在,如果我在user表上有一个搜索函数,它在名称和电子邮件上使用SQL like -clause(例如:SELECT * FROM user_table u,其中的u.name如“frog%”或u)。像“frog%”这样的电子邮件),我的“邪恶”下午请求我提供另一个“来自给定组的搜索用户”函数,该函数的行为与原始搜索函数相同,但只返回来自给定组的用户。这里,我面对的是一个包含两个表的函数,它的部分逻辑(搜索相关子句)在userDAO中。这个函数应该放在哪里?

1 个解决方案

#1


2  

Your first design has a higher normalization than your second one.

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

Both the "list all users in a group" and "list all groups for a user" should go to the relationDAO.

“列出一个组中的所有用户”和“列出一个用户的所有组”都应该指向relationship dao。

This is because you will simply have:

这是因为你只需要:

public IEnumerable getUsersForGroup(int groupId);

and

public IEnumerable getGroupsForUser(int userId);

The

one DAO for each table

每个表一个DAO

rule refers not to this kind of situations, but rather to the fact that you should not have two user DAOs for instance.

规则不是指这种情况,而是指您不应该有两个用户DAOs。

To summarize, I would go with the first design, as it makes more sense in the context of relational database design, and I would place the mentioned query in the relation DAO.

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


推荐阅读
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
author-avatar
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有