【发布时间】:2015-11-23 04:37:39
【问题描述】:
我正在尝试设计一个非常简单的表格来存储社区中朋友的数据。
因此我分别存储了2个朋友的userId。
目标
用户想要加载他/她的朋友列表。
t_friends 选项 1:
查询
SELECT * FROM t_friend WHRE user_id = 10
10 是正在查找好友列表的用户的当前userId,并且他有1 个好友userId(20)
这样userId (10) 可以找到他的朋友(20) 但是如果userId(20) 正在寻找他的朋友呢?
查询加上userId。
这让我想到了另一个包含冗余数据的设计:
t_friends 选项 2:
userId (10) 立即加载:
SELECT * FROM t_friend WHRE user_id=10
类似于userId(20) 的查询将是:
SELECT * FROM t_friend WHRE user_id=20
但是冗余呢?这导致我使用表设计选项 1 进行该查询:
SELECT * FROM t_friend WHERE user_id=10 OR friend_id=10
我觉得有一种更聪明的方法可以解决这个问题。您对这种结构有任何经验吗?
谢谢
【问题讨论】:
-
冗余怎么样?你所做的非常好,没有更聪明的方法,不管有人会写什么。您查询用户的朋友。您的数据已标准化,一切都很完美。如果您可以通过尝试“优化”来实现任何目标,那么它就会破坏整个事情,创建不必要的复杂查询并使系统难以维护。无论谁或有什么使用 SQL 的经验,当人们看到您创建的表时 - 乍一看,一切都非常合理。 TL;DR:不要改变任何东西。
-
谢谢@Mjh。但是这样我们就有了两倍的数据。而不是例如10GB 你将有 20GB 扫描等等。
-
@bub 您使用的最终查询非常好,在我看来问题是被过度思考了。每个关系一行,使用 OR 查询,完成。你可以在里面扔一个 IF 来避免它在 php 中:
SELECT IF(user_id=10, friend_id, user_id) AS target_id FROM t_friend WHERE user_id=10 OR friend_id=10 -
您正在解决一个数据过多的问题,方法是实现一个通过“机智”系统获取关系的复杂过程——这是无法完成的。此外,如果您考虑到存储要求 - 10 或 20 GB 真的很小。如果您的列是 4 字节整数,那么在任何压缩开始之前,每条记录花费 12 个字节,等于
833, 333, 333行。不要通过破坏逻辑和破坏数据库的工作方式来解决存储问题。 @ChrisBaker 还提供了一个出色的解决方案,您可以实施该解决方案来弥补冗余。 -
另外一件事,特别是如果你关心表的物理数据大小,去掉id字段,让主键是user_id和friend_id的组合。那里不需要一个任意的自增数字,人们不能多次成为朋友,所以主键自然是两个用户 ID 的组合。
标签: php mysql database redundancy