2011-02-28 85 views
0

我不知道如果標題實際上使得任何意義,但這裏是我的一般問題:設計架構屬性

我有一個跨多個不同的保存有關事件的信息表設備和平臺。我不知道如何有效地設計架構查詢所有事件,然後查詢特定事件的信息。

我試圖保持它下面的所有僞代碼,所以如果事情不與代碼是有意義的,這只是因爲我試圖保持它的通用。

這裏是一個人爲的例子:

Event Table: 
    int Id 
    datetime Occured_On 
    uniqueidentifier UserId --> Users table 
    int Category (the type of event) --> Categories table 
    text Summary (textual summary of the event) 
    text EventSource (specifies whether this is a DesktopEvent or MobileEvent) 

然後,每個設備有它自己的一套用於每個事件的數據。例如:

DesktopEvent 
    int Id 
    int EventId --> Event table 
    text Hostname 
    text LoggedInUsername 

MobileEvent 
    int Id 
    int EventId --> Event table 
    int PlatformId 
    text ESN 

... 

我想查詢事件表中最近X個最新的事件。現在,我現在有一個列指定事件的來源,這樣我可以做第二次查詢到相應的表。

results = SELECT * FROM Event DESCENDING Occured_On LIMIT 5. 

foreach (result in results) 
{ 
    if (result.EventSource == "DesktopEvent") 
     data = SELECT * FROM DestkopEvent WHERE EventId == result.EventId 

    ... 
} 

雖然這看起來效率很低。

它進一步複雜化有可能是事件的許多不同的來源,而不是僅僅2(DesktopEvent和MobileEvent)像上面。嘗試連接10個以上的表,檢查哪一個不是NULL,似乎比上面的更糟糕。

是否有更好的方法來組織這些數據?非常感謝。

回答

2

在數據建模,你有時會發現事情並非完全不同,但也AREN」 t完全一樣。它們有一些共同的特徵,所以它們並沒有完全不同。但他們每個人都有一些獨特的屬性,所以他們不完全一樣。

屬性通用於所有這些事情,在一個表中屬於彼此。該表通常稱爲超類型。

每個獨特的屬性集屬於不同的表格;這些表稱爲亞型。在數據建模中,「超類型」和「子類型」與使用相同單詞的面向對象編程概念沒有任何關係。相同的話,意義完全不同。小心一點。

聽起來像表「事件」是你的超類型。 「桌面事件」和「移動事件」是幾個子類型中的兩個。

如果是這樣,您可能是在正確的軌道上。低效率只是顯而易見的,而不是真實的。真實的事實是,桌面事件和移動事件對你來說是不同的事情,所以它們必須存儲在不同的表中。並將它們存儲在不同的表中使得完整性約束實現起來非常簡單。畢竟,這是SQL數據庫設計的目的。查詢可以利用索引。

通常,超類型和'n'子類型映射到'n'+ 1個表格和'n'個視圖。每個'n'個子類型都有一個表格,並且還有一個超類型表格。您還可以爲每個子類型構建一個視圖;每個視圖將一個子類型連接到超類型。您通常會使用視圖,而不是直接使用子類型表。但是,您可以直接使用超類型表 - 例如,獲取最後五個事件。

搜索條件超類型和子類型。 SO用戶PerformaceDBA和我都已經多次寫過關於它們的內容。 (向其他人關注關係超類型和子類型的道歉;我記住名字有很多麻煩)。

+0

感謝您確認我的想法。我想我試圖說服自己,有這麼多的個人亞型是錯誤的。但是,鑑於它們是不同的類型,對它們進行不同的模型是有意義的。 – mfanto 2011-03-02 06:55:53

1

一種選擇是存儲在一個EAV風格表中的所有此類事件特定的數據:

http://en.wikipedia.org/wiki/Entity-attribute-value_model

因此,你可能只需要2個表 - 事件表和EVENT_DETAILS表。舉例來說,如果你有一個桌面事件ID = 12,則可能必須在EVENT_DETAILS表如下:

1, 12, hostname, myhost 
2, 12, loggedInName, myname 
... 
25, 17, esn, <esn value> 
etc. 

所以你在一個臺上混合了不同事件類型的詳細數據。這個可能是對查詢效率更低,但它是一個簡單的,很好理解的模型,可以用於擴展性和數據動態處理/視圖。

如果您需要優化這樣的事情,你可能看面向列的DBS:

http://en.wikipedia.org/wiki/Column-oriented_DBMS

+0

感謝您的鏈接。我認爲,因爲某些子類型屬性是關係型的,所以僅使用單個表格仍然有意義,所以我可以保持參照完整性。雖然我沒有真正閱讀過EAV,所以我很欣賞這個鏈接。 – mfanto 2011-03-02 06:50:53

1

您應該在SQL中執行連接,而不是在應用程序代碼中執行兩個查詢。

例如

SELECT * FROM (
SELECT de.*, e.* 
FROM DestkopEvent de , Event e 
WHERE EventId == e.EventId 
ORDER BY e.occurred_on desc 
) 
WHERE rownum < 6 

的想法是離開查詢執行的複雜性,數據庫,而不是在應用程序代碼處理。另外,您可以添加索引以進一步優化查詢。但實質上,如果您正在尋找優化 - 那麼請考慮數據庫而不是思考應用程序。