我已经构建了一个产品数据库,该数据库分为3部分。每个部分都有一个包含标签的“子”部分。但是我越用它就感觉越不稳定。我每次添加它都需要越来越多的代码才能使它工作。
产品由零件构成,每个零件都是一种类型。每种产品,零件和类型都有一个标签。每种语言都有一个标签。
产品包含2个列表中的部分。一个默认部件列表(每种类型之一)和一个可选部件。
现在我想在混合中添加货币,并决定重新模拟我处理这个问题的整个方式。
我想得到的结果是所有产品对象的列表,其中包含与部件匹配的名称,描述,价格,所有部件和所有类型。对于这些正确的语言标签。
像这样:
product
- name
- description (by language)
- price (by currency)
- parts
- part (type name and part name by language)
- partPrice (by currency)
我当前设置的问题是db.ReferenceProperty和db.ListProperty(db.key)的混合
获取所有数据有点麻烦,需要多个for循环,匹配dict和数据存储区调用。好吧,这有点乱。
重新模型(未经测试)看起来像这样
class Products(db.model)
name = db.StringProperty()
imageUrl = db.StringProperty()
optionalParts = db.ListProperty(db.Key)
defaultParts = db.ListProperty(db.Key)
active = db.BooleanProperty(default=True)
@property
def itemId(self):
return self.key().id()
class ProductPartTypes(db.Model):
name= db.StringProperty()
@property
def itemId(self):
return self.key().id()
class ProductParts(db.Model):
name = db.StringProperty()
type = db.ReferenceProperty(ProductPartTypes)
imageUrl = db.StringProperty()
parts = db.ListProperty(db.Key)
@property
def itemId(self):
return self.key().id()
class Labels(db.Model)
key = db.StringProperty() #want to store a key here
language = db.StringProperty()
label = db.StringProperty()
class Price(db.Model)
key = db.StringProperty() #want to store a key here
language = db.StringProperty()
price = db.IntegerProperty()
这里最重要的是我将标签和价格分开了。因此,这些可以包含任何产品,零件或类型的标签和价格。
所以我很好奇,从架构的角度来看,这是一个可靠的解决方案吗?即使每个模型中有数千个条目,这是否会成立?
此外,欢迎任何以良好方式检索数据的提示。我目前的解决方案是首先获取所有数据并将其循环并将其粘贴在dicts中,但感觉它可能会在任何时候失败。
..弗雷德里克
答案 0 :(得分:3)
您需要记住,App Engine的数据存储区要求您重新考虑通常的数据库设计方法。它首先违背直觉,但如果您希望应用程序可扩展,则必须尽可能地对数据进行非规范化。数据存储区就是这样设计的。
我通常采用的方法是首先考虑在不同的用例中需要进行哪种查询,例如。我需要同时检索哪些数据?按什么顺序?应该索引哪些属性?
如果我理解正确,您的主要目标是获取包含完整详细信息的产品列表。顺便说一句,如果您有其他查询方案 - 即。过滤价格,类型等 - 你也应该考虑它们。
为了从一个查询中获取所需的所有数据,我建议你创建一个看起来像这样的模型:
class ProductPart(db.Model):
product_name = db.StringProperty()
product_image_url = db.StringProperty()
product_active = db.BooleanProperty(default=True)
product_description = db.StringListProperty(indexed=False) # Contains product description in all languages
part_name = db.StringProperty()
part_image_url = db.StringProperty()
part_type = db.StringListProperty(indexed=False) # Contains part type in all languages
part_label = db.StringListProperty(indexed=False) # Contains part label in all languages
part_price = db.ListProperty(float, indexed=False) # Contains part price in all currencies
part_default = db.BooleanProperty()
part_optional = db.BooleanProperty()
关于此解决方案:
显然,采用这种设计的数据存储区中会有很多冗余 - 但这没关系,因为它允许您以可扩展的方式查询数据存储区。
此外,这并不是您想要的架构的替代品,而是一个专门为您需要做的面向用户的查询而设计的附加模型,即。检索完整的产品/零件信息列表。
这些ProductPart实体可以由后台任务填充,复制位于其他规范化实体中的数据,这些实体将是权威数据源。由于App Engine上有足够的数据存储空间,因此这不应该是一个问题。
答案 1 :(得分:1)
IMO你的设计大多有意义。在阅读完问题陈述后,我确实提出了几乎相同的设计。有几点不同
part_types = ('wheel', 'break', 'mirror')
它还取决于您预期的查询类型。如果有很多关于自然价格计算的查询(独立于产品和零件信息的其余部分),那么按照您的方式进行设计可能是有意义的。
您已经提到过,您将首先获得所有数据。是不是可以查询?如果你在你的应用程序中获得整个数据,然后在python中进行排序/过滤,那么它会很慢。你在考虑哪个数据库?对我来说,mongodb在这里看起来是个不错的选择。
最后为什么你甚至怀疑1000条记录?您可以事先在db上运行一些测试。
贝斯茨