番石榴表替代品

时间:2012-12-12 08:31:38

标签: java guava

我们有分区数据库,每个用户的数据都存储在特定的服务器上。

我的用例非常简单:

  • 用户有对话。
  • 对于一个对话,在数据库中有两个代表记录(每个用户都有自己的对话记录)。

如果是用户的删除操作,我想删除每个用户之间的所有对话。也就是说,我需要删除每个服务器中与用户相关的所有会话。我迫切需要每台服务器分组数据。

Table<Integer, Integer, Set<Integer>> setPerUser = HashBasedTable.create();

for(Conversation conversation : conversations) {
   Integer serverIndex = getServerForUser(conversation);
   Integer userId = conversation.getUserId();
   Set<Integer> uci = setPerUser.get(serverIndex, userId);
   if(uci == null) {
      uci = Sets.newHashSet();
      setPerUser.put(serverIndex, userId, uci);
   }
   uci.add(conversation.id);
}

一开始我认为每一行都可以代表服务器和列用户。 看来Table数据结构不适合这种情况。在这种情况下,Table表示的数据太稀疏。虽然表可以表示M x N数据,但我只有M + N个数据。

表示此数据的正确数据结构是什么?

编辑:

当然Table可以处理这种情况,但我不确定它是否适合这个问题。让我想到Table的是有行和列方法,这意味着一个复杂的算法。在我的用例中,列有一个值,这意味着每个用户只有一个对应的服务器,但每行有多个值意味着每个服务器有多个用户。

1 个答案:

答案 0 :(得分:3)

我认为使用现有的数据结构不适用于您的用例。

相反,您应该设计与您的数据相对应的对象:

public Class User{
  int id;
  Set<Conversation> conversations;
}

public class Conversation{
  int id;
  Set<User> parcipitants;
}

(在两种情况下都省略了Getters,Setters,equals()/ hashCode())

现在保留两张地图来查找用户和对话:

private Map<Integer, Conversation> conversationsById;
private Map<Integer, User> usersById;

编写getOrCreateConversation(Integer id)getOrCreateUser(Integer id)等方法

此外,您应该考虑使用JPA或Hibernate等持久性技术,因为这些技术非常适合维护这种关系。