1

我已經構建了一個產品數據庫,它分爲3部分。每個部分都有一個包含標籤的「子」部分。但我越用它工作越不穩定。而且每增加一項,我都需要越來越多的代碼才能實現它。在Google App Engine上設計可擴展的產品數據庫

產品是由零件構成的,每個零件都是一種類型。每個產品,部件和類型都有一個標籤。每種語言都有一個標籤。

產品包含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循環,匹配字典和數據存儲調用。那有點混亂。

重新模型(未測試)看起來像這樣

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() 

這裏主要的事情是,我已經分裂的標籤,價格出來。所以這些可以包含任何產品,零件或類型的標籤和價格。

所以我很好奇,從建築的角度來看,這是一個堅實的解決方案嗎?即使每個模型中有數千個條目,這是否仍然成立?

此外,任何提示以良好的方式檢索數據是值得歡迎的。我目前的解決方案是首先獲取所有數據,然後循環使用它們並將它們粘在字典中,但感覺它可能會失敗。

..fredrik

回答

1

IMO您的設計大多是有道理的。在閱讀完您的問題陳述後,我確實想出了幾乎相同的設計。有一些差異

  • 我的產品和ProductPart的價格不是作爲單獨的表格。
  • 其他區別是part_types。如果沒有多少part_type,你可以簡單地把它們作爲python list/tuple。

part_types = ('wheel', 'break', 'mirror')

這也取決於那種你正期待查詢。如果有許多關於自然價格計算的查詢(獨立於產品和零件信息的其餘部分),那麼設計它的方式可能是有意義的。

你已經提到你將首先獲得所有的數據。不查詢可能嗎?如果你在你的應用中獲得整個數據,然後在python中進行排序/過濾,那麼速度會很慢。你在考慮哪個數據庫?對我來說,mongodb在這裏看起來很不錯。

最後爲什麼你甚至懷疑1000條記錄?你可以預先在你的db上運行一些測試。

最好成績

+0

謝謝。單獨價格的原因是產品包含每種語言(貨幣)的一種價格,而類型則相同。每種類型都有一個基於當前語言的標籤。有沒有一種方法可以用一些語言支持來使用元組? – fredrik 2010-09-24 12:05:35

+0

我想獲取所有數據一次(每個表至少一個數據),所以我不會以一個新的查詢結束upp,以便在產品循環播放時爲其獲取標籤。 – fredrik 2010-09-24 12:07:08

+0

IMO正確的方法是以十進制格式存儲價格,然後您應該使用適當的框架實用程序以期望的貨幣格式顯示。 – Shekhar 2010-09-24 12:38:37

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() 

關於此解決方案:

  • ListProperties設置到 indexed = False,以避免 爆炸索引,如果你不需要 來篩選它們。
  • 爲了獲得正確的 描述,標籤或類型,您必須始終以相同的順序設置 列表值。 例如:part_label [0]是 英語,part_label [1]是西班牙語, 等。價格和 貨幣的相同想法。
  • 從這個 模型獲取實體後,你將不得不做一些 內存的操作,以 得到很好的數據結構 你想要的方式,也許在一個新的字典。

很明顯,在這樣的設計下,數據存儲中會有很多冗餘 - 但沒關係,因爲它允許您以可伸縮的方式查詢數據存儲。此外,這並不意味着替代您所考慮的體系結構,而是專門爲您需要執行的面向用戶的查詢而設計的附加模型,即,檢索完整產品/零件信息清單。

這些ProductPart實體可以由後臺任務填充,複製位於其他規範化實體中的數據,這些規範化實體可能是權威數據源。由於App Engine上有大量數據存儲空間,因此這不成問題。

+0

我真的很喜歡背景的想法!我正在考慮一個綜合解決方案。我的解決方案適用於您所描述的邏輯和後臺任務。然後結果嘗試獲取非規格化數據(如果存在),或者對我的模型進行查詢。什麼是爆炸指數? – fredrik 2010-09-24 15:56:26

+0

ps。感謝您更正我的拼寫和語法:) – fredrik 2010-09-24 16:00:28

+1

以下是有關爆炸索引的一些信息:http://code.google.com/appengine/docs/python/datastore/queriesandindexes.html#Big_Entities_and_Exploding_Indexes – Franck 2010-09-24 17:14:16