客观化 POST/LIKE/USER 关系
Objectify POST/LIKE/USER Relationship
我正在使用 objectify 对 google 数据存储进行建模,我的部分数据存储具有以下 3 个元素:
用户 post 一个新的 Post 可以被很多用户喜欢(典型的社交网络)。
到目前为止我有用户:
@Entity
public class UserMW {
@Id
private Long id;
@Index
private String email;
...
}
Post:
@Entity
public class PostMW{
@Id
private Long id;
@Load
private Ref<UserMW> owner;
...
}
喜欢:
@Entity
public class LikeMW {
@Id
private Long id;
@Load
private Ref<UserMW> user;
private Key likedObject;
...
}
它运行完美,满足我到目前为止的所有需求。现在的问题是我不知道我应该去哪条路不像 post(从种类 Likes 中删除一个实体)。
我有 User 和 likedObject 键来删除它,所以如果它在关系数据库中会非常简单(只需按 userID 和 likedObjectID 使用 "where" 删除)但是在 Objectify 上...
我可以考虑两种方法:
1 - Likes 实体的两个属性上的@index 然后查询它并删除(但是@Index 太贵了 table Likes 会很大!!听起来不是个好主意)
2 - @Parent 在 Likes 实体的用户属性上,@Index 在 likedObject 上,然后按祖先查询,然后按 likedObject 键过滤并删除(但如果我使用@Parent,我一直明白我加载 1 个用户我'我会载入他所有的赞,正如我所说,table 赞将是巨大的!!听起来也不是个好主意)
有什么建议可以解决我的问题吗?
谢谢大家!
我会向 Like
实体添加另一个索引,因为这是最简单的工作解决方案,特别是考虑到 datastore's newish pricing 这也使它更便宜:
...writing a single entity only costs 1 write regardless of indexes and
will now cost [=11=].18 per 100,000. This means writes are more affordable
for people using multiple indexes. You can use as many indexes as your
application needs without increases in write costs.
请注意,索引仍会占用存储空间并可能影响性能,但您在使用它们时可以更加自由一些...
是的,您可以像关系数据库一样简单地索引 user
和 likedObject
字段以及 运行 查询。但是,这有两个缺点:
- 查询最终一致
- 您没有利用内存缓存
强一致性是可取的,这样如果用户 likes/unlikes 某些东西并重新加载页面,他们可以保证立即看到效果。
我会这样做:
@Entity
@Cache
public class Like {
@Parent
private Ref<User> user;
@Id
private String likedObjectKey;
public <T> Key<T> getLiked() { return Key.create(likedObjectKey); }
}
使用被点赞的toWebSafeString()
键作为Like
实体的字符串id。您可以添加一些语法糖来隐藏 stringification/destringification.
这意味着为 {user, thing} 元组获取 Like
s 始终是一个 get-by-key 操作。您可以批量获取它们,并且获取将利用内存缓存(正面和负面的命中都将被缓存)。结果总是高度一致的。您可以轻松地在交易中获取和修改这些。
注意这不会让你问这个问题"who liked this thing?"你可能也想要将喜欢的对象键作为普通索引字段存储在Like
.即使您不立即打算使用它,我也会强烈推荐它;你最终会想要 运行 这个查询,即使只是为了调试。索引并不像大家担心的那么贵。
我正在使用 objectify 对 google 数据存储进行建模,我的部分数据存储具有以下 3 个元素:
用户 post 一个新的 Post 可以被很多用户喜欢(典型的社交网络)。
到目前为止我有用户:
@Entity
public class UserMW {
@Id
private Long id;
@Index
private String email;
...
}
Post:
@Entity
public class PostMW{
@Id
private Long id;
@Load
private Ref<UserMW> owner;
...
}
喜欢:
@Entity
public class LikeMW {
@Id
private Long id;
@Load
private Ref<UserMW> user;
private Key likedObject;
...
}
它运行完美,满足我到目前为止的所有需求。现在的问题是我不知道我应该去哪条路不像 post(从种类 Likes 中删除一个实体)。
我有 User 和 likedObject 键来删除它,所以如果它在关系数据库中会非常简单(只需按 userID 和 likedObjectID 使用 "where" 删除)但是在 Objectify 上...
我可以考虑两种方法:
1 - Likes 实体的两个属性上的@index 然后查询它并删除(但是@Index 太贵了 table Likes 会很大!!听起来不是个好主意)
2 - @Parent 在 Likes 实体的用户属性上,@Index 在 likedObject 上,然后按祖先查询,然后按 likedObject 键过滤并删除(但如果我使用@Parent,我一直明白我加载 1 个用户我'我会载入他所有的赞,正如我所说,table 赞将是巨大的!!听起来也不是个好主意)
有什么建议可以解决我的问题吗?
谢谢大家!
我会向 Like
实体添加另一个索引,因为这是最简单的工作解决方案,特别是考虑到 datastore's newish pricing 这也使它更便宜:
...writing a single entity only costs 1 write regardless of indexes and will now cost [=11=].18 per 100,000. This means writes are more affordable for people using multiple indexes. You can use as many indexes as your application needs without increases in write costs.
请注意,索引仍会占用存储空间并可能影响性能,但您在使用它们时可以更加自由一些...
是的,您可以像关系数据库一样简单地索引 user
和 likedObject
字段以及 运行 查询。但是,这有两个缺点:
- 查询最终一致
- 您没有利用内存缓存
强一致性是可取的,这样如果用户 likes/unlikes 某些东西并重新加载页面,他们可以保证立即看到效果。
我会这样做:
@Entity
@Cache
public class Like {
@Parent
private Ref<User> user;
@Id
private String likedObjectKey;
public <T> Key<T> getLiked() { return Key.create(likedObjectKey); }
}
使用被点赞的toWebSafeString()
键作为Like
实体的字符串id。您可以添加一些语法糖来隐藏 stringification/destringification.
这意味着为 {user, thing} 元组获取 Like
s 始终是一个 get-by-key 操作。您可以批量获取它们,并且获取将利用内存缓存(正面和负面的命中都将被缓存)。结果总是高度一致的。您可以轻松地在交易中获取和修改这些。
注意这不会让你问这个问题"who liked this thing?"你可能也想要将喜欢的对象键作为普通索引字段存储在Like
.即使您不立即打算使用它,我也会强烈推荐它;你最终会想要 运行 这个查询,即使只是为了调试。索引并不像大家担心的那么贵。