2012-05-28 14 views
0

我需要存儲值每天的時間表,即數據庫的每個用戶都應該有狀態分配給每一天,就像這樣:存儲數據的範圍 - 有效的代表

from 1.1.2000 to 28.05.2011 - status 1 
from 29.05.2011 to 30.01.2012 - status 3 
from 1.2.2012 to infinity - status 4 

每天只能有一個狀態分配和最後的狀態沒有結束(直到另一個給出)。我的問題是什麼是在SQL數據庫中的有效表示?顯而易見的解決方案是爲每一個變化(最後一天的狀態在每個範圍被分配)行,像這樣:

uptodate  status 
28.05.2011 status 1 
30.01.2012 status 3 
01.01.9999 status 4 

這有很多問題 - 如果我希望添加另一個範圍,從15.02說0.2012,我將需要改變最後一排也:

uptodate  status 
28.05.2011 status 1 
30.01.2012 status 3 
14.02.2012 status 4 
01.01.9999 status 8 

,它需要大量的檢查,以確保不存在重疊和錯誤,特別是如果有人要修改範圍列表中的中間 - 插入從2012年1月29日至2012年2月10日的新狀態很難實現(這將需要狀態3和狀態4的數據範圍相應地縮小以騰出空間用於新狀態) 。有沒有更好的解決方案?


我想過完全地其他的解決辦法,比如存儲單獨的行每一天的狀態 - 所以會有排了每天的時間表。這樣可以很容易地進行更新 - 只需在開始和結束日期之間輸入新行狀態即可。當然,這會產生大量不必要的數據,所以這是一個糟糕的解決方案,但是一致且易於管理。我想知道中間是否有什麼東西,但我想不是。


更多的上下文:我希望主持人能夠自由地分配任何日期,並編輯它,如果他需要的話。但大多數版主會在最後添加新的狀態數據範圍。我並不需要最後的狀態。主持人完成整個月的編輯後,我需要根據當月每天的狀態生成raport。但任何時候主持人都可能想要在幾個月前編輯數據(這將反映在更新的賽事上),並且他可以提前一年提前一個狀態。

+2

你可以試試'fromdate',而不是'uptodate'。 – Howard

+0

@霍華德我想過,但這並不能解決我的問題。上傳看起來更容易管理。 – Deadeye

+0

如果大部分狀態變化都發生在時間線的「現在」一端,我傾向於同意@Howard。這避免了頻繁更新結束時間行的工作。至於變化的歷史,你堅持進入並擺弄一行或多行。請注意,在兩端都沒有佔位符,您實際上並未表示您的第一個示例行。如果您將12.11.1999的狀態42添加到11.12.1999,那麼您如何建議處理尚未存儲的1.1.2000日期?或者連續統一體中的其他任何缺陷? 'DateQuantizedTimeOffset'? – HABO

回答

1

您似乎想要將這張表用於兩件事情 - 記錄當前狀態和狀態變化的歷史。你應該分離出來的當前狀態並將其移動到父(就像註冊日期)

User 
=============== 
Registered Date 
Current Status 

Status History 
=============== 
Uptodate 
Status 
+0

我真的不需要最後的狀態 - 我用更多的上下文更新瞭如何使用這些數據的問題。 – Deadeye

0

你的表結構應該包括狀態期間的有效日期和結束日期。這有效地將狀態「拼貼」成不重疊的組。最後一行應該有一個虛擬結束日期(如上所述)或NULL。如果您在結束日期有索引,則使用值而不是NULL是有用的。

通過這種結構,以獲得在任何給定日期的狀態,您可以使用查詢:

select * 
from t 
where <date> between effdate and enddate 

要在週期的末尾添加一個新的狀態需要兩個變化:

  1. 使用enddate = 01/01/9999修改表中的行,使其具有昨天的結束日期。
  2. 插入新行,今天的effdate和01/01/9999

的結束日期我想在存儲過程中這個包起來。

要在過去某個日期更改狀態,需要將其中一個歷史記錄分成兩部分。多個日期可能需要更改多個記錄。

如果你有一個日期範圍,就可以得到重疊給定的時間內與查詢所有瓷磚:

select * 
from t 
where <periodstart> <= enddate and <periodend> >= effdate