我有两张桌子:
auth
包含身份验证信息users
包含用户个人资料信息 auth
有一个username
列。这既可以作为登录凭据,也可以作为用户个人资料网址的一部分(例如example.com/profiles/username
)。
检索用户列表时,需要使用其用户名来设置其个人资料的网址。目前,我查询users
表并加入auth
表以获取此信息。但是,如果username
也是users
中的列,则可以避免该连接,从而在两个不同的表中创建两个相同的列。
我不喜欢重复列的想法,但少一个连接总是好的。这是否需要重新编写数据库模式(或其他内容)的标志,或者这是冗余可接受的情况的示例?
答案 0 :(得分:7)
规范化模式(即删除冗余)并非旨在及时解决效率问题,而是a)空间效率(通过消除重复的数据副本)和b)一致性(通过不在多个位置存储相同的信息,你不冒险让他们不同意)。从这个角度来看,必须使用联接是这些其他好处的成本。
答案 1 :(得分:1)
如果没有更广泛的应用图片,很难给出好的答案。我个人认为复制用户名等信息并不是一个好主意。
当你做出这样的设计决定时,你应该考虑系统维护/未来的发展等几点:
希望这会有所帮助。
答案 2 :(得分:1)
“少一次加入总是好的”。我对此提出异议。数据库旨在将表连接在一起。额外的连接通常需要工作,例如:
虽然这听起来像是很多工作,但实际上最多只需要几毫秒的努力。
如果第二个表适合内存 - 或者在索引中包含用户名字段,那么第二个读取不是必需的 - 那么这一切都发生得非常快。不可否认,如果您尝试从平庸的硬件中获得每秒5,000笔交易,那么您可能会关心。在大多数情况下,额外的几毫秒(最多!)并不昂贵。
这项额外的工作会给你带来什么?它确保用户名是最新的用户名(如果已更改)。
您的申请可能还有其他要求。性能可能是关键的,在这种情况下,对数据进行非规范化可能是有用的(尽管复合索引可能在性能上非常接近)。您可能处于内存有限的环境中,在这种情况下,在单个页面中读取所有用户数据可能很重要。用户名可能永远不会更改,在这种情况下,您可能会考虑将用户名作为表中的主键。也就是说,在某种情况下,非规范化将是一个严肃的选择。
肯定还有其他案例。例如,几乎所有的分析都来自非规范化数据结构。