【问题标题】:Datastore design: 1 large class vs. 2 classes vs. polymodel?数据存储设计:1 个大类与 2 个类与多模型?
【发布时间】:2014-01-19 21:37:20
【问题描述】:

我有兴趣了解为 Google App Engine 的数据存储区设计类的几种方法的优缺点。

考虑以下类:

选项 0

class Car(db.Model):
    title = db.StringProperty()
    year = db.StringProperty()
    imgurl = db.StringProperty()
    type = db.StringProperty()
    addeddate = db.DateTimeProperty()
    external_id = db.IntegerProperty()
    # possibly 5 or 6 more properties

class Part(db.Model):
    title = db.StringProperty()
    # other stuff

部件的父级在创建时始终设置为相应的汽车。

它们有多种使用方式:

  • 查询+列表(+排序)部分:列出部分时,我需要显示汽车的标题,并获取它的external_id和年份(所以我不需要所有内容,而是通过访问部分获取整个汽车实体.parent,我已经在使用父级预取)。
  • 查询+列表(+排序)汽车:只需要标题、年份和imgurl。
  • get car:包含所有汽车详细信息的页面,需要所有属性。

考虑到我获取和显示数据的方式,上述设计与以下设计之间的最佳选择(提供优缺点)是什么?

选项 1

class Car(db.Model):
    title = db.StringProperty()
    year = db.StringProperty()
    imgurl = db.StringProperty()

class CarEx(db.Model):
    type = db.StringProperty()
    addeddate = db.DateTimeProperty()
    external_id = db.IntegerProperty()
    # possibly 5 or 6 more properties
  • 专业人士:在获取 Parts 时,获取父级 (Car) 的速度更快,因为属性较少。

  • Con:显示汽车时,我们需要获取 CarEx。添加汽车时需要再添加一个实体。删除汽车时需要删除 CarEx。

选项 2

class Car(db.PolyModel):
    title = db.StringProperty()
    year = db.StringProperty()
    imgurl = db.StringProperty()

class CarEx(Car):
    type = db.StringProperty()
    addeddate = db.DateTimeProperty()
    external_id = db.IntegerProperty()
    # possibly 5 or 6 more properties

添加汽车时,我们只会添加 CarEx 实体。

  • 专业版:获取 Parts 时,获取父级 (Car) 更快,因为属性较少。 ???我实际上完全不确定这是真的。 ???

  • 专业人士:当显示汽车时,我们会得到 CarEx。无需获取另一个实体。添加和删​​除汽车就像只有 1 个包含所有内容的汽车模型一样简单(选项 0)。

  • Con:添加 CarEx 时额外写入。其他额外费用?

因此,总的来说,我需要能够获取零件(以及它们的父级,而不需要大量成本),并且我需要在单独的页面上获取完整的汽车。我不确定我对 PolyModel 的假设是否正确,也不确定是否有任何其他隐藏的优点/缺点,甚至其他选项。

【问题讨论】:

    标签: google-app-engine database-design google-cloud-datastore


    【解决方案1】:

    几点,如果你刚开始,你真的应该使用ndb。

    您列出的少量属性不会对使用 Car 和 CarEx 产生足够的影响。特别是如果您一直需要 CarEx。

    考虑到 PolyModel 的工作原理,您使用 PolyModel 没有意义。 Polymodel 会更适合

    class Vehicle(PolyModel):
        title = StringProperty
        year = StringProperty()
        addeddate = db.DateTimeProperty()
        external_id = db.IntegerProperty()
        # possibly 5 or 6 more properties
    
    
    class Car(Vehicle):
        doors = IntegerProperty
    
    class Van(Vehicle):
        carrying_capacity = FloatProperty() #(m3)
    
    class Truck(Vehicle):
        tray_length = IntegerProperty()
    

    是的,做作,属性。但现在我可以通过任何核心 Vehicle 属性搜索所有车辆并获得 Trucks、Vans 和 Cars。你不能用普通的模型继承来做到这一点。如果没有 PolyModel,您将不得不分别搜索 Car、Truck 实体类型。

    在你的情况下,你可能不需要这个。

    您对Parts 的处理在很大程度上取决于您需要它们的数量和频率。如果您的 Parts 可能少于 1MB,并且在需要 Parts 时需要所有 Parts,那么请考虑将 Parts 存储在单个容器实体中,并使用重复的 StructuredProperty 来存储它们。然后,当您需要零件时,您可以在单个实体中获取它们。如果您只需要一些部分,则将它们存储为单独的实体。

    如果您需要超过 1MB 的部件,但您始终需要所有部件,则使用多个容器。

    您确实需要查看特定视图的使用频率,如果您需要所有信息还是其中的一些信息,以确定最佳策略。

    【讨论】:

    • 不幸的是,切换到 ndb 将是一个长期的决定,因为我已经用 db 完成了一切。 “您列出的少量物业不会对使用 Car 和 CarEx 产生足够的影响。特别是如果您一直需要 CarEx。” -> 你认为什么是“少数属性”?你有数字来支持这个说法吗?我并不总是需要 CarEx,我有很多充满零件的视图(约 50 个零件/页),我在其中获取所有父母只是为了访问他们的标题/年份/external_id,这就是为什么我假设一辆小型汽车(零件的parent) 会提高性能。
    • 在 ndb 上足够公平。无法判断你是否开始。至于模型大小和性能,这是 2 辆 Car 和 ExCar 的往返时间与 unpick protobuf 的时间的情况。老实说,您应该同时介绍两者。考虑到设计的复杂性,我不会为少于 20 个属性而烦恼。但是你需要描述你的用例。
    • 鉴于零件与汽车的绑定如此紧密,如果您知道始终需要将数据复制到零件中,那为什么还要提取父级,这将为您节省一笔费用,如果你在一个页面上显示 50 个端口,这将节省 50 次获取,这比稍微大一点的对象要好得多
    • 即使我在 1 .get() 中获得了 50 辆母车(仍然要获取 50 个实体),所以我最终将所需的数据(名称、external_id)添加到零件本身以完全避免去找父母,因为他们的名字和身份证几乎永远不会改变。谢谢。
    猜你喜欢
    • 2015-05-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 2016-11-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-19
    • 1970-01-01
    相关资源
    最近更新 更多