一切都在一个" table"在应用引擎?

时间:2014-10-15 15:44:19

标签: google-app-engine objectify

这个问题涉及使用app引擎和客观化的数据库设计。我想讨论将所有(或者说多个)实体放入单个“表”的方法的利弊。

假设我有两个实体的(非常简化的)数据模型:

class User {
    @Index Long userId;
    String name;
}

class Message {
    @Index Long messageId;
    String message;
    private Ref<User> recipient;
}

乍一看,把它们放在同一个“桌子”中是没有意义的,因为它们完全不同。

但是让我们来看看当我想搜索所有实体时会发生什么。假设我想找到并返回符合某些搜索条件的用户和消息。在传统的数据库设计中,我要么做两个单独的搜索请求,要么在写入期间创建一个单独的索引“表”,我会冗余地重复字段,这样我以后可以在一个搜索请求中检索项目。

现在让我们来看看以下设计。假设我会使用一个存储所有内容的实体。数据存储区将如下所示:

Type | userId | messageId | Name | Message

USER | 123456 | empty | Jeff | empty
MESSAGE | empty | 789012 | Mark | This is text.

看看我想去哪里?我现在可以搜索一个名称,并在一个请求中找到所有用户和消息。我甚至可以添加一个索引字段,比如

@Index List index;

到“common”实体,不需要两次写入数据。

鉴于数据存储区的行为,它在搜索空的索引字段时永远不会返回记录,并将其与部分索引相结合,我还可以通过查询给定Type的唯一字段来获取用户或消息。 / p>

只要许多字段为空,存储长(非标准化)记录的成本不会高于存储单个记录的成本。

我看到了进一步的优势:

  • 我也可以使用相同的“表格”进行审核,就像每条记录一样 存储将形成“历史”条目(只要我不允许 更新,在这种情况下我需要手动处理)。
  • 我可以在不扩展数据库架构的情况下轻松添加新类型。
  • 当通过REST返回搜索结果时,我可以将它们返回到一个列表中,并且客户端会查看类型。

也可能存在缺点,例如缓存,但可能没有。我现在看不到这一点。

那里有人试图沿着这条路走下去,或者看到这种做法存在严重缺陷吗?

2 个答案:

答案 0 :(得分:2)

这实际上是Google数据存储区的工作原理。您的所有实体(以及其他所有实体)都存储在一个大致相同的BigTable中:

{yourappid}/{key}/{serialized blob of your entity data}

索引存储在所有应用程序共享的三个BigTable中。在我对这个问题的回答中,我试着详细解释这一点:efficient searching using appengine datastore ancestor paths

所以,为了重新解释一下你的问题,让谷歌维持善良或者将自己保留在自己的财产中是否更好?

简短的回答是,让Google维护种类会使得查询所有种类更加困难,但可以更轻松地在一种类型中进行查询。自己维护伪类可以更容易地查询所有类型,但是在一种类型中查询更加困难。

当谷歌按照正常使用方式维护种类时,您已经理解了这一限制 - 无法对所有不同类型的属性进行过滤。另一方面,使用带有自己的描述符的单个Kind意味着每次查询时都必须添加一个额外的filter()子句:

 ofy().load().type(Anything.class).filter("discriminator", "User").filter("name >", "j")

有时这些多过滤器查询可以通过zigzag合并来满足,但有些不能。甚至那些能够满足之字形的那些也不那么有效。事实上,这可以解释Z字形的特定退化情况 - 像识别器这样的低基数属性。

您最好的选择是仔细挑选您的共享种类。 Objectify使您更容易使用多态:https://code.google.com/p/objectify-appengine/wiki/Entities#Polymorphism 多态类型层次结构共享一个Kind(基类@Entity的种类); Objectify为您管理鉴别器属性,并确保ofy().load().type(Subclass.class)之类的查询转换为正确的过滤操作。

我建议谨慎使用此功能。

答案 1 :(得分:1)

一个严重的缺点是索引:

你所做的每一个查询都会编写一个单独的索引来进行操作,然后你所做的所有写操作都需要写入所有这些表(没有理由,在很多情况下)。

我目前无法想到其他缺点,除了每个实体的兆兆限制(如果你有很多类型,有很多值,你可能会遇到这种情况,因为你最终有一大堆专栏)

没有提到你的ONE实体模型会有多大,以及你的代码可能会如何错综复杂地进行分类&#34;您的实体类型可能最终成为