2011-09-29 72 views
0

我正在構建一個分佈式會計系統。 就數據庫結構和要求而言,將應用程序描述爲類似Twitter的應用程序可能最容易,但是具有14個表的分層DB結構。 使用該應用程序的公司可能有1個或更多用戶,全部共享公司信息。AppEngine數據存儲需要設計建議

目前,每個實體代表一個記錄類型,即客戶,發票等。 所有實體都有一個父應用程序的用戶。 (用於HRD查詢一致性原因)

對數據庫的每個查詢都由14個AppEngine查詢組成。每個桌子一個。 該查詢涉及屬性過濾。

新的要求是,用戶查詢可能需要基於其他每個用戶的不同屬性值。 這意味着我們需要(14 x公司用戶的數量)AppEngine查詢。這似乎太多了。

,可以通過屬性過濾無類型祖先查詢將是非常好的,唉,沒有做不到的:)

我的選擇是:

  1. 設置實體類型爲用戶。沒有父母。這意味着所有記錄類型都是混合的。 (過濾的字段存在於所有記錄類型中)。 這並不漂亮。但你會考慮這個嗎?

  2. 只有過濾器才具有固定的實體類型和查詢。結果相當於Kindless祖先查詢。但是,我擔心在多用戶使用中會很慢。

一些數字: 我們計劃爲10,000家公司,平均每家公司5個用戶和1至5萬條記錄每條記錄的類型。 (×14總)

感謝您的耐心迄今爲止.. :)

+0

爲什麼每個查詢都需要查詢所有的表?這似乎是一個非常奇怪的要求。 –

+0

@Nick,應用程序有一個分佈式數據庫。每個客戶都有一個DB的本地副本,其中包含與該客戶相關的信息。每個查詢需要在整個數據庫中查找所有新的/已更改的信息,並將數據傳輸到客戶端以供本地使用。 (每個查詢將在幾乎所有表中找到更改) – OferR

回答

1

老實說,我發現它具有挑戰性的按照你的描述,所以這可能是關閉基地。看到你現有的代碼可能會有所幫助。但是我知道你想要一個有效的替代方法來處理有錢的無情祖先查詢,所以我們從這裏開始。

考慮去規範化數據模型,以包括元實體只是爲了查詢:

class User(db.Model): 
    pass 

class OwnedObject(db.Expando): 
    object_key = db.StringProperty() 

class Customer(db.Model): 
    name = db.StringProperty() 
    created_on = db.DateProperty() 

class Invoice(db.Model): 
    amount = db.IntegerProperty() 
    created_on = db.DateProperty() 

# on write 
customer = Customer() 
customer.name = name 
customer.created_on = date.today() 
customer.put() 

user = User(key_name=users.get_current_user().user_id()) 

owned_object = OwnedObject(parent=user) 
owned_object.object_key = customer.key() 
owned_object.created_on = customer.created_on 
owned_object.put() 

# on read 
query = OwnedObject.all() 
query.ancestor(user) 
query.filter('created_on =', date.today()) 

entities = db.get([x.object_key for x in query]) 

所以在這裏你正在做的寫,減少對讀更多的工作。

每個真實實體都與一個OwnedObject實體耦合,該實體從適當的祖先下降並指向真實實體的密鑰。 OwnedObject是一個expando,因此您將熱切地分配您想要查詢的任何屬性(在本例中爲created_on)。

上閱讀,您可以查詢您複製到expando元實體的任何屬性,你可以拉回來一個用戶的所有對象使用一個查詢和一批獲取的固定開銷。

編輯:通過使用PolyModel,您可以在沒有元實體的情況下完成類似的任務。

+0

Thanks @Drew。你理解我的問題100%。與我的解決方案選項1(在問題的主體中)相比,您的解決方案具有將基礎實體保持在可管理的「每個記錄類型的實體」中的優勢。缺點是增加了維護元實體和兩步讀取的開銷。你認爲這值得嗎?像選項1中的一個混亂的實體是一個很大的禁忌?你怎麼看? – OferR

+0

我想你的例子中使用jdo我不熟悉,但我相信我有這個想法。 jdo如何實現最後一行(db.get([...])?我猜jdo發佈了多個db.get(),因爲平臺IN()限制爲30個項目(將讀取PolyModel) – OferR

+0

我想我的第一個猜測是錯誤的。它是Python :)(我使用java +原生AppEngine類)。 PolyModel似乎不適合我的數據庫設計。它自然處理類似類型的數據(繼承)。另一方面,Expando是一種實現我的解決方案選項1的方法。 – OferR