Каков наилучший способ хранения исторических данных в SQL Server 2005/2008? - PullRequest
22 голосов
/ 17 ноября 2008

Вот мой упрощенный и надуманный пример: -

Допустим, я хочу измерять и хранить температуру (и другие значения) во всех городах мира на ежедневной основе. Я ищу оптимальный способ хранения данных, чтобы было так же легко получить текущую температуру во всех городах, как и исторически получить всю температуру в одном городе.

Это достаточно простая проблема, но я ищу лучшее решение.

2 основных варианта, о которых я могу подумать, следующие: -

Вариант 1 - в той же таблице хранятся текущие и исторические записи

Хранить все текущие и архивные записи в одной таблице.

т.е.

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 записей), а данные актуальны в течение одного дня. Текущие данные будут так же вероятны, как и исторические.

Ответы [ 7 ]

13 голосов
/ 17 ноября 2008

это ЗАВИСИТ от шаблонов использования приложений ... Если шаблоны использования указывают, что исторические данные будут запрашиваться чаще, чем текущие значения, то поместите их все в одну таблицу ... Но если исторические запросы являются исключением, ( или менее 10% запросов), и производительность более распространенного запроса текущего значения будет зависеть от помещения всех данных в одну таблицу, тогда имеет смысл разделить эти данные в своей собственной таблице ...

5 голосов
/ 17 ноября 2008

Я бы держал данные в одной таблице , если только у вас нет очень серьезного смещения для текущих данных (в использовании) или исторических данных (в объеме). Составной индекс с DATE + TOWNID (в таком порядке) в большинстве случаев устраняет проблему производительности (хотя, очевидно, у нас нет данных, чтобы быть уверенными в этом на данный момент).

Единственное, что меня интересует, это то, что кому-то понадобятся данные из текущих и исторических данных для города. Если это так, вы просто создали по крайней мере одно новое представление для беспокойства и возможной проблемы с производительностью в этом направлении.

Это, к сожалению, одна из тех вещей, где вам может потребоваться профилировать ваши решения на основе реальных данных. Я лично использовал составные индексы, такие как указанные выше, во многих случаях, и все же есть несколько крайних случаев, когда я решил разбить историю на другую таблицу. Ну, на самом деле это еще один файл данных, потому что проблема была в том, что история была настолько плотной , что я создал для нее новый файл данных, чтобы избежать раздувания всего набора основных файлов данных. Проблемы производительности редко решаются теорией.

Я бы порекомендовал прочитать подсказки запросов для использования индексов и "охватить индексы" для получения дополнительной информации о проблемах производительности.

3 голосов
/ 17 ноября 2008

Ваша таблица очень узкая и, вероятно, будет работать в одной правильно проиндексированной таблице, которая никогда не превысит возможности SQL Server в традиционной нормализованной модели OLTP даже для миллионов и миллионов строк. Даже при использовании модели с двумя таблицами преимущества можно уменьшить с помощью разделения таблиц в SQL Server. Поэтому рекомендовать его по модели с одним столом не так уж и много. Это будет сценарий в стиле Inmon или «Хранилище корпоративных данных».

В гораздо больших сценариях я бы регулярно передавал данные в хранилище данных (смоделировано с помощью размерной модели в стиле Кимбалла) и просто очищал живые данные - в некоторых простых сценариях, таких как ваш, это могло бы быть эффективно НЕТ живые данные - все идет прямо в хранилище. У многомерной модели есть много преимуществ при разрезании данных различными способами и хранении огромного количества фактов с различными измерениями. Даже в сценарии хранилища данных таблицы фактов часто делятся по дате.

Может показаться, что ваши данные не имеют этого (Город и Дата - ваши единственные явные измерения), однако в большинстве хранилищ данных измерения могут иметь снежный покров или могут быть избыточными, поэтому в факте, хранящемся в факте, могут быть другие измерения. время загрузки вместо «снежинки» для большей эффективности - например, State, Zip Code, WasItRaining, IsStationUrban (продолжение).

Это может показаться глупым, но когда вы начинаете собирать данные для результатов в хранилищах данных, это заставляет задавать вопросы, такие как - в день с дождем в городских условиях, какова была средняя температура в штате Мэн? - это немного проще, не объединяя целую кучу таблиц (т.е. это не требует большого опыта в вашей нормализованной модели и работает очень быстро). Вроде как бесполезная статистика в бейсболе - но некоторые, очевидно, оказываются полезными.

1 голос
/ 17 ноября 2008

Другой альтернативой может быть использование одной таблицы для всех данных и просмотр текущей температуры. Это не поможет производительности, но может улучшить читаемость / ремонтопригодность. Вы можете даже использовать индексированное представление для повышения производительности, если у вас есть соответствующая версия sql.

1 голос
/ 17 ноября 2008

Я предлагаю сохранить в той же таблице, так как исторические данные запрашиваются так же часто. Если только вы не добавите в таблицу еще много столбцов.

Когда размер становится проблемой, вы можете разбить его на десятилетия и сохранить хранимую процедуру, объединяющую запрошенные строки.

0 голосов
/ 27 апреля 2016

Если вы храните все в одной таблице, как вы собираетесь создать реляционную базу данных.

Пример:

Идентификатор -------------- GUID ---- PK

record_id ------- GUID

каждый раз, когда будет вставлена ​​новая запись, [id] будет меняться, но [record_id] останется прежним Теперь, если вам нужно связать его с адресной таблицей, как вы собираетесь это сделать?

0 голосов
/ 17 ноября 2008

Я бы использовал одну таблицу с индексными представлениями, чтобы предоставить мне самую свежую информацию. Серверы SQL 2005 и 2008 предназначены для хранилищ данных, поэтому должны хорошо выполнять предварительную обработку в этих условиях.

Если у вас есть шаблон данных, который часто требует записи в базу данных, то лучшим выбором будет иметь активную таблицу и таблицу архива, которые вы обновляете через некоторое время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...