我在GAE上使用Objectify作为我的DAO层,我想让我的实体的大多数软删除能够,使这些实体使用isActive布尔扩展父类是一个好主意,还是应该使用嵌入式或者我应该使用嵌入式只是让它成为一个界面isSoftDeleteable?
我要问的原因是,Objectify似乎将Entity与相同的父级类存储在同一个实体类中(至少从我在_ah / admin中看到的内容)并且当所有内容都在同一个实体类型下时它可能会减慢查询速度,也许?
哪种方法最好,或者在GAE中有更好的方法进行软删除?
请提前通知并提前致谢!
答案 0 :(得分:5)
这个问题没有一个正确的答案。最佳解决方案主要取决于您的实体在任何给定时间可能处于删除状态的百分比。
一个选项是存储@Index(IfTrue.class) boolean active;
之类的字段,并将此过滤器添加到所有查询中:
ofy.load().type(Thing.class).filter("size >", 20).filter("active", true)
这样做的缺点是它需要添加额外的索引 - 可能有几个,因为你现在可能需要多属性索引,其中单属性索引就足够了。
或者,您可以存储“已删除”标记,并从查询结果中手动排除已删除的实体。维护的索引较少,但是当您拉回不需要的记录时,它会为每个查询增加额外的开销。如果您删除的条目很少,则无关紧要。
最后一招。您可能会发现最好将索引存储为已删除的日期,因为它可能最有用:@Index Date deleted;
这使您filter("deleted", null)
可以获取活动项目,还可以按日期戳来过滤以获取您可能真正的旧实体希望清除。但是,请注意,这将导致删除的日期索引到任何多属性索引,如果您有大量已删除的实体,可能会显着增加索引大小。在这种情况下,您可能希望@Index(IfNull.class) Date deleted;
并使用map-reduce清除足够旧的实体。
答案 1 :(得分:1)
我同意StickFigure的回答。利用“空”索引和“空”索引之间的区别。权衡是每次写入都会产生更多的数据存储区写操作 - 当您添加索引时,每次更新该值时,至少需要2个额外的写操作(升序和降序)索引。当您删除索引时,它会再写2次。就个人而言,我认为这是值得的。
每当您对实体类的单个属性进行查询时,查询时间应该是相当可预测的,因为如果您考虑在封面下发生了什么,那么在进行并行批处理之前,您将按顺序浏览项目列表实体数据