我有一个app引擎项目(java),它有一个User类。我想建立一个廉价的朋友关系系统。每个用户最多可以有50个朋友。我想做一些像zany这样的事情:
class User {
String username;
Text friends; // "joe,mary,frank,pete"
}
其中“friends”是用户是朋友的用户名的逗号分隔列表。以下是我想要支持的操作以及我如何使用上述操作:
获取我的完整好友列表
只需查看User对象,返回以逗号分隔的朋友列表。
添加朋友
获取我的用户对象,检查字符串中是否存在目标名称,如果不存在,则追加到末尾。将修改后的User对象保留回数据存储。
删除朋友
获取我的用户对象,检查字符串中是否存在目标名称,如果存在,则从字符串中删除它。将修改后的User对象保留回数据存储。
两个用户是共同的朋友
获取两个用户对象,检查用户名是否出现在另一个用户对象上。
获取完整的朋友列表对我的应用程序非常重要,将每个关系存储为一个单独的实体对我来说似乎是噩梦(当用户需要查看他们的朋友列表可能会破坏我时,从数据存储中获取每个实体)。我希望Text属性的简单读取会更轻量级。
检查共同朋友的情况似乎是这里最大的缺点,但不会经常发生。我不知道是否从数据存储区中获取两个User对象并进行字符串比较在性能方面会是灾难性的。可以吗?我想我可能还读到,从数据存储创建和删除对象不仅仅需要修改现有对象。所以添加/删除朋友的操作也可能更好。
很高兴听到有关这种或更优化方式的任何想法。
谢谢
--------------------------更新-------------------- -
根据Adrian的评论,我也可以做以下事情:
class User {
String username;
List<String> friends;
// or //
Set<String> friends;
}
所以我认为如果我使用List,那么这些实体将默认为索引编制。我不确定是否可以执行GQL查询,因为知道列表被索引以获得匹配而不实际获取任何实体。类似的东西:
SELECT COUNT FROM User WHERE
(username = "me" && friends = "bob") &&
(username = "bob" && friends = "me")
如果我加载了两个User对象,那么存储为Set将有助于更快地进行搜索,但我认为对于List和Set,从数据存储区取出时必须花费额外的时间对它们进行反序列化,因此不确定它们是否为好处被否定了。也许它会比它有所帮助更伤害?
答案 0 :(得分:1)
List<String> friends;
是一个很好的解决方案,也是我在专业用途中看到的解决方案。如果朋友拥有您的应用或Google的用户ID,则可以使用该数据类型代替密钥列表。
答案 1 :(得分:1)
我实际上建议您以两种形式存储数据。首先是用户名列表,其次是这些用户自己的实体的数据存储区键的匹配列表。
这将允许您快速显示用户的朋友,并查找一个特定的朋友以检查相互关系。特别是,检查朋友的原始用户密钥的朋友密钥列表比在字符串上匹配几乎肯定更有效。
唯一的缺点是保持两个列表同步,但给出的操作列表听起来并不太难。