2

我正在使用Firebird 2.1,並且正在尋找解決此問題的最佳方法。數據庫設計問題 - 哪個是最好的解決方案?

我在寫日曆應用程序。不同用戶的日曆條目存儲在大日曆表中。每個日曆條目可以有一個提醒集 - 只有一個提醒/條目。

統計上,日曆表隨着時間的推移可能會增長到數十萬條記錄,而將會有更少的提醒。

我需要在不斷的基礎上查詢提醒。

哪一個是最好的選擇?

a)儲存在日曆表提醒信息(在這種情況下,我要查詢成千上萬的記錄IsReminder = 1)

B)創建一個單獨的提醒表,只包含C)我可以在Reminders表中存儲關於提醒的所有信息,然後只查詢這個表格,然後查詢這個表格,然後查詢這兩個表格(或者可以在其上創建一個視圖)

C) 。缺點是一些信息需要在兩個表中重複,例如爲了顯示提醒,我需要知道並將事件的開始時間存儲在提醒表中 - 因此我維護着兩個具有相同值的表。

您認爲如何?

還有一個問題:日曆表將包含多個用戶的日曆,僅由用戶ID字段分隔。由於只能有4-5個用戶,即使我在這個領域提供了一個索引,它的選擇性也會非常糟糕 - 這對於擁有數十萬條記錄的表來說並不好。有沒有解決方法?

謝謝!

回答

2

這三種選擇都有優點和缺點。一個人最好取決於你沒有提供的細節。一般來說,如果您設置的索引允許正確的檢索策略,請不要過多地從十萬箇中選擇三個或四個條目。如果不懂索引,無論你做出三種選擇中的哪一種,你都可能會遇到麻煩。

如果是我,我會選擇B.我還會在提醒表中存儲提醒的任何屬性。

要非常小心您是通過單獨的EventId還是通過(UserId,EventId)標識事件。如果您選擇後者,則應該使用Event表的複合主鍵。不要太擔心複合主鍵,特別是Firebird。
如果聲明覆合主鍵,請注意聲明(UserId,EventId)不會與聲明(EventId,UserId)具有相同的結果。它們在邏輯上是等價的,但在兩種情況下,自動生成的索引的結構將不同。

這反過來會影響查詢,如「找到一個給定用戶的所有提醒」的速度。

再次,如果是我的話,我會避免選擇C.引進有害的冗餘性的模式與它承載了一段精心設計的編程責任,當你去更新數據。否則,您最終可能會在數據庫的不同位置存儲一個存儲相同事實的矛盾版本的數據庫。

而且,如果你真的想知道perfromance的影響,嘗試所有三種方法,使用測試數據負載,並做你自己的基準。

+0

感謝您的回覆無遺:-)如果用戶名不是一個複合主鍵的一部分,而是一個簡單的現場與索引,我想它的選擇性將是十分糟糕,檢索速度慢? – Steve 2010-11-19 14:33:18

+0

@Steve:索引是爲了快速查詢而發明的 - 如果你有一個帶有索引的字段,應該可以使用這個索引編寫查詢。 – 2010-11-19 14:38:16

+0

Doc,我讀過Firebird的索引選擇性是一個重要的因素。如果一個字段具有低折射率的選擇性(只有幾個不同的值),你可能看不到的速度增長...... – Steve 2010-11-19 15:28:20

0

我認爲您需要創建逼真的虛假用戶數據,並測量您希望運行的一些典型查詢的差異。

索引,查詢優化和您需要的查詢結果的類型可以產生很大的差異,因此在不瞭解更多信息的情況下很難說出什麼是最好的。

0

當選擇選項(A),你應該

  • 提供「IsReminder」索引(或任何最適合您的預定查詢上IsReminder,用戶ID,組合指數)
  • 確保查詢使用此索引

如果每個提醒需要存儲多個布爾標誌(例如,用戶在事件發生前通知的分鐘數),則選項B優於A。但是,你應該猜測你的程序中你將不得不加入兩個表。

如果可以,避免選項C.如果你不想基準所有三種情況下,我建議用A或B開始,根據所描述的情況,很可能你選擇的解決方案將是速度不夠快,所以你不必打擾其他案件。

+0

醫生,感謝您的信息,但您使用火鳥?因爲FB在索引方面是特殊的...(請參閱我上面的註釋) – Steve 2010-11-19 15:30:45