2013-03-10 25 views
0

我注意到現在看起來非常明顯的模式。 需要得到您對此的意見。關係模型中OneToMany關係性能的一般設計原則

假設在關係模型中具有表1到表2之間的一對多關係。 例如,表1可以是用戶表,表2可以是登錄所有用戶登錄的登錄表。一個用戶可以多次登錄。 給定一個用戶,我們可以找到該用戶的所有登錄。

想到的第一個想法是僅將登錄名存儲在登錄表中。這是設計之一。

但是,如果由於某種usecases我們感興趣的用戶的特定登錄(說上次登錄的)是「通常是個好主意」緩存在用戶表本身的最後登錄時間。 是嗎?

設計2顯然是多餘的,因爲我們總能找到通過執行加入,然後丟棄所有,但先前登錄上次登錄的時間。

對於一個用戶應該沒問題。但是如果你想爲所有的用戶找到一個SQL查詢的最後登錄時間,那麼設計1將涉及一個連接和一個子查詢來過濾不需要的結果。

但考慮到我們的用例,是去年的登錄時間存儲在用戶表本身,這將拯救我們從加入一個好主意。是對的嗎?

這是您在設計模式時看到的通用模式嗎?

+0

我認爲當前會話ID通常用於跟蹤這一點。 – Aiias 2013-03-10 05:21:21

+0

我剛剛用這個作爲例子,我指的是通用許多設計原則。另外,我想製作這個問題社區維基。 – 2013-03-10 05:24:20

+0

您正在評估設計階段的性能方面。請記住,[過早優化是所有邪惡的根源](http://en.wikipedia.org/wiki/Premature_optimization#When_to_optimize) – 2013-03-10 05:43:29

回答

0

您正在混淆TABLE和RELATION這兩個常見錯誤的概念。您的概念模型中有兩個關係(用戶&登錄),但實際上這將涉及物理模型中的兩個以上表,因爲非聚集索引不過是附加表來加速多個關係的加入。

一旦登錄中存在INDEX(用戶標識,登錄時間)以支持與用戶的FK關係,則非聚集索引將覆蓋查找用戶最近登錄的查詢。只有當這個默認模型已經確定了一個已知的,可測量的,嚴重的性能問題時,纔會看到非規範化,因爲這個(像所有的非規範化)在非規格化表上引入了對每一個其他讀和寫操作的性能命中。

+0

嗯...有趣...可能是我缺少重點......但是當我查詢所有用戶的最近登錄時,我將生成一個如下所示的查詢: 'SELECT user.id,login.login_time FROM USER用戶,登錄登錄WHERE user.id = login.user_id AND login.login_time> =(從LOGIN where user_id = user.id)選擇登錄時間''。那是對的嗎?非聚集索引如何加快此查詢速度? 存在此索引時,以下查詢會更快嗎? 'SELECT U.id,L1.login_time FROM USER U1,LOGIN L1,LOGIN L2 WHERE U1.id = L1.user_id AND U1.id = L2.user_id AND L1.login_time> = L2.login_time'。 – 2013-03-10 19:45:11

+0

我猜這些查詢存在一些問題。需要弄清楚如何解決它們。假設這種連接對'非聚集索引'是有效的,那麼我將需要確保hibernate在使用hbm2ddl時爲我生成這些索引,並確保我的JPQL轉換爲更高效的SQL查詢。在某些情況下,我看到只是創建一個冗餘列使得最終的數據分析速度更快。雖然我沒有創建相關的非聚集索引。 – 2013-03-10 20:12:07

+0

查詢「用戶u上的UserName,u.UserID,LastLoginTime = Max(LoginTIme)」將u.UserId = l.UserID組中的Logins l留在了u.UserID組中,UserName「將被非聚集索引覆蓋。 – 2013-03-11 01:54:31