2012-02-10 28 views
0

良好的初步實踐我有消息對於SQL消息表

Key - UserId, MsgIndex 
C1...Cn - some data columns 
Cn+1 - Date, when message has been added to the table. 

問題是做客戶的最佳實踐的表...

客戶詢問是否有新郵件服務器...

有2個選項來做到這一點:

  1. 檢查郵件與index > lastRxMsgIndex(客戶端將保存最後味精不知疲倦X收到)
  2. 檢查郵件與date > lastRxMsgDate(客戶端將保存最後RX味精與日期服務器將獲得味精結果時,它給他)

哪一個更好,更快......

保持日期/ TS或索引是相同的,常識表示保持日期/ TS但msg索引相同。

MsgIndex是在表的主鍵,以便它應該是快於搜索的日期(當用戶將有很多消息...)

這是最好的辦法嗎?

感謝 約阿夫

回答

2

首先就表現:你可以索引添加到您的日期列,以提高搜索的日期的性能。您很可能還想在索引中包含user_id。例如,您可以在(user_id, id)(user_id, date)上使用組合索引,這樣個人用戶可以快速查找他們擁有的消息,而無需服務器也掃描其他用戶的消息。

關於功能:使用日期時間作爲關鍵點的一個潛在問題是時間戳是而不是通常是唯一的。如果您根據日期進行搜索,則可能(但不太可能)您會錯過一條消息。下面是一個示例場景演示問題:


在16:01:04.312表中包含兩條消息:

id date     message 
1  2012-02-10 14:23:54 foo 
2  2012-02-10 16:01:04 bar 

客戶已經收到第1行以前和現在請求和接收最新的行:

SELECT * FROM your_table WHERE date > '2012-02-10 14:23:54' 
(1 row) 

然後,在16:01:04.420一個新行進入相同的時間戳的數據庫:

id date     message 
1  2012-02-10 14:23:54 foo 
2  2012-02-10 16:01:04 bar 
3  2012-02-10 16:01:04 baz 

客戶端請求的最新行,但沒有得到它:

SELECT * FROM your_table WHERE date > '2012-02-10 16:01:04' 
(0 rows) 

另一個問題是,如果服務器的時間向後調整。這可能會導致以後的消息以較早的時間戳插入。如果您使用日期查找最新消息,這些消息也將被忽略。最好使用id來避免這些潛在的問題。

2

由於MsgIndex是主鍵,它有一個索引。所以通過MsgIndex的訪問比使用日期比較要快得多。

1

如果您有很多傳入消息,則前面提到的方式可以保證工作。後一種方式,如果你在同一天有2條消息(說同一秒,因爲我不認爲你可以更細粒度),你擰了;)

我用'去索引'方法之前,當我在一個每秒接收大量消息的系統上工作時。

1

如果您在日期字段上有一個索引,那麼應該沒有任何區別(假設您使用的是unix時間戳),因爲您有兩個整數升序的字段,您希望整數更大的所有帖子比X.

在timestamp列中存在非唯一值的可能性,但除非使用聚合函數,否則這不會成爲問題,在這種情況下,您可以通過在字段中包含唯一主鍵來修復它你選擇。

鑑於這個事實,你只需要考慮:

  • 無論日期列上每次插入數據計算指數的(很小)的開銷是值得的
  • 無論你的代碼使用ids或使用時間戳,寫入更具可讀性。

就我個人而言,我會選擇時間戳字段,因爲它立即清晰地告訴其他人閱讀代碼你正在做什麼,而使用id有點模糊,索引開銷微不足道。