簡體   English   中英

在 SQL Server 2005/2008 中存儲歷史數據的最佳方式是什么?

[英]What is the best way to store historical data in SQL Server 2005/2008?

我的簡化和人為的例子如下:-

假設我想每天測量和存儲世界上所有城鎮的溫度(和其他值)。 我正在尋找一種存儲數據的最佳方式,以便獲取所有城鎮的當前溫度就像獲取一個城鎮的所有歷史溫度一樣容易。

這是一個很容易解決的問題,但我正在尋找最佳解決方案。

我能想到的兩個主要選項如下:-

選項 1 - 同一個表存儲當前和歷史記錄

將所有當前和存檔記錄存儲在同一個表中。

IE

CREATE TABLE [dbo].[WeatherMeasurement](
  MeasurementID [int] Identity(1,1) NOT Null,
  TownID [int] Not Null,
  Temp [int] NOT Null,
  Date [datetime] NOT Null,
)

這將使一切變得簡單,但是獲取城鎮列表和當前溫度的最有效查詢是什么? 一旦表中有數百萬行,這會擴展嗎? 在表中添加某種 IsCurrent 標志有什么好處嗎?

選項 2 - 將所有存檔記錄存儲在單獨的表中

將有一個表來存儲當前的實時測量值

CREATE TABLE [dbo].[WeatherMeasurement](
  MeasurementID [int] Identity(1,1) NOT Null,
  TownID [int] Not Null,
  Temp [int] NOT Null,
  Date [datetime] NOT Null,
)

以及存儲歷史存檔日期的表(可能由觸發器插入)

CREATE TABLE [dbo].[WeatherMeasurementHistory](
  MeasurementID [int] Identity(1,1) NOT Null,
  TownID [int] Not Null,
  Temp [int] NOT Null,
  Date [datetime] NOT Null,
)

這具有保持主要當前數據精簡且查詢非常高效的優點,但代價是使模式更復雜和插入數據更昂貴。

哪個是最好的選擇? 有沒有我沒有提到的更好的選擇?

注意:我簡化了架構以幫助更好地關注我的問題,但假設每天都會插入大量數據(100,000 條記錄),並且數據是一天的最新數據。 當前數據與歷史數據一樣有可能被查詢。

它取決於應用程序的使用模式......如果使用模式表明歷史數據將比當前值更頻繁地查詢,那么將它們全部放在一個表中......但是如果歷史查詢是例外,(或少於10% 的查詢),並且更常見的當前值查詢的性能將受到將所有數據放在一個表中的影響,那么將這些數據分離到它自己的表中是有意義的......

我會將數據保存在一張表中,除非您對當前數據(使用中)或歷史數據(數量)有非常嚴重的偏見。 在大多數情況下,帶有 DATE + TOWNID(按此順序)的復合索引將消除性能問題(盡管顯然我們目前沒有數據來確定這一點)。

我想知道的一件事是是否有人想要來自城鎮的當前和歷史數據的數據。 如果是這樣,您至少創建了一個新視圖來擔心該方向可能出現的性能問題。

不幸的是,這是您可能需要根據現實世界數據分析您的解決方案的事情之一。 我個人在很多情況下都使用了上面指定的復合索引,但也有一些邊緣情況我選擇將歷史記錄分解到另一個表中。 嗯,實際上是另一個數據文件,因為問題是歷史記錄密集了,我單獨為它創建了一個新的數據文件,以避免使整個主數據文件集膨脹。 性能問題很少通過理論來解決。

我建議閱讀索引使用的查詢提示,並“覆蓋索引”以獲取有關性能問題的更多信息。

您的表非常狹窄,可能會在單個正確索引的表中執行,該表永遠不會超過 SQL Server 在傳統規范化 OLTP 模型中的容量,即使對於數百萬行也是如此。 即使使用雙表模型,也可以通過在 SQL Server 中使用表分區來減輕優勢。 所以與單表模型相比,它沒有太多值得推薦的地方。 這將是 Inmon 風格或“企業數據倉庫”場景。

在更大的場景中,我會定期將數據傳輸到數據倉庫(使用 Kimball 風格的維度模型建模)並簡單地清除實時數據 - 在像您這樣的一些簡單場景中,可能實際上沒有實時數據 -這一切都直接進入倉庫。 維度模型在以不同方式對數據進行切片並存儲具有各種維度的大量事實時具有很多優勢。 即使在數據倉庫場景中,事實表也經常按日期分區。

您的數據似乎沒有這個(城鎮和日期是您唯一的顯式維度),但是,在大多數數據倉庫中,維度可能會雪花狀或可能存在冗余,因此在加載時存儲的事實會有其他維度而不是使用雪花來提高效率——比如 State、Zip Code、WasItRaining、IsStationUrban(人為設計的)。

這可能看起來很愚蠢,但是當您開始在數據倉庫中挖掘數據以獲取結果時,就會提出以下問題:在城市環境下雨的一天,緬因州的平均溫度是多少? - 只是在不加入一大堆表格的情況下更容易上手(即它不需要很多關於規范化模型的專業知識並且執行速度非常快)。 有點像棒球中無用的統計數據 - 但有些顯然是有用的。

我建議保留在同一張表中,因為查詢歷史數據的頻率一樣高。 除非您將向表中添加更多列。

當大小成為問題時,您可以按十年將其分區,並使用存儲過程聯合請求的行。

另一種選擇可能是為所有數據查找一個表並查看當前溫度。 這對性能沒有幫助,但可以很好地提高可讀性/可維護性。 如果您有合適的 sql 版本,您甚至可以使用索引視圖來提高性能。

我將使用帶有索引視圖的單個表來為我提供最新信息。 SQL 2005 和 2008 服務器是為數據倉庫設計的,因此在這種情況下應該能很好地執行。

如果您有一個需要經常寫入數據庫的數據模式,那么最好的選擇是擁有一個活動表和存檔表,您可以在某個時間間隔批量更新。

如果您將所有內容存儲在一張表中,您將如何制作關系數據庫。

例子:

id--------------GUID----PK

record_id-------GUID

每次插入新記錄時,[id] 都會改變,但 [record_id] 將保持不變。 現在,如果您必須將它與地址表鏈接起來,您將如何做到這一點?

與其嘗試為此優化關系數據庫,不如考慮使用時間序列數據庫 這些已經針對處理基於時間的數據進行了優化。 它們的一些優點是:

  • 查詢基於時間的鍵更快
  • 大數據吞吐量
    • 由於默認操作只是一個附加操作,因此可以很快完成。 InfluxDb支持數以百萬計的數據點每秒)。
  • 能夠更積極地壓縮數據
  • 對時間序列數據更加用戶友好。
    • API 傾向於反映時間序列數據的典型用例
    • 可以自動計算聚合指標(例如窗口平均值)
    • 通常可以使用特定的可視化工具。

我個人喜歡使用開源數據庫InfluxDB ,但也有其他不錯的選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM