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