Вопрос разработки: лучший подход для хранения и получения дельт в таблице SQL - PullRequest
0 голосов
/ 25 декабря 2018

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

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

Данные из этой хронологической таблицы не извлекаются ежедневно.Для этой цели у меня есть таблица транзакций типа * 1 Current Design.Вот детали моей реализации.

1) Текущий дизайн

enter image description here

2) Планируемый дизайн - 1

enter image description here

Вопрос:

1) Если я использую приведенную выше структуру таблицы, каков лучший запрос , чтобы получить результаты, подобные показаннымТекущий дизайн # 1

3) Планируемый дизайн - 2

enter image description here enter image description here

Вопрос:

1) Насколько сильно ударить по производительности, можно сравнить с плановым дизайном №1.

2) Кроме того, если я пойду по этому маршруту, то какой лучший запрос получитрезультаты, подобные показанным в текущем дизайне № 1?

Конечный вопрос:

Я предполагаю, что запланированный дизайн # 1 займет больше табличного пространства против запланированного дизайна # 2.Но запланированный дизайн 2 займет больше времени для получения запроса.Есть ли какой-то случай, который, как я предполагаю, может пойти не так?

Редактировать: У меня есть только вставки, идущие к этой таблице.Никаких обновлений или удалений к этому никогда не делается.

Ответы [ 2 ]

0 голосов
/ 31 декабря 2018

У меня похожая ситуация, когда я загружаю несколько датчиков температуры каждые 10 секунд.Поскольку я использую экспресс-версию MSSQL, я смотрю на максимальный размер базы данных 10 ГБ, поэтому я проявил изобретательность, чтобы сделать его как можно дольше.Моя табличная раскладка в значительной степени идентична вашей в том, что у меня есть 1 отметка времени + 30 столбцов значений + еще 30 столбцов флагов.

  • Столбцы значений являются числовыми (9,2)
  • Столбцы значений помечаются как SPARSE, если значение идентично (достаточно) значению, перед которым я сохраняю NULL вместо повторения значения.
  • Столбцы флагов являются битовыми и указывают, является ли значение 'extrapolated 'или из фактического источника (позже)

У меня также есть другая таблица, которая содержит следующую информацию для каждого датчика:

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

В любом случае, пока мой поток информации таков, что у меня есть несколько программ, каждая из которых считывает данные из разныхисточники (arduino, web, ...) и дамп это в .csv файлах, а затем программа 'parser', которая время от времени считывает эти файлы в базу данных.Поскольку я загружаю значения 1 на 1, а не на основе строк, это не очень эффективно, но сейчас я делаю около 3500 значений в секунду, поэтому я не слишком обеспокоен.Я согласен, что это верно только при загрузке значений в историческом порядке и потому, что я использую вспомогательную таблицу.

В настоящее время у меня есть почти год информации, что соответствует

  • 2.209.883 строк
  • 5.799.511 значений распределены по 18 датчикам (да, у меня еще есть место для еще 12 без необходимости менять таблицу)

Это означает, что у меня заполнено только 15% полей или, если посмотреть на это с другой стороны, когда я заполняю каждую запись, а не ставлю NULL в случае повторения, я бы почти 8 разтам столько чисел.

Что касается требований к месту: я решил перезагрузить все номера прошлой ночью «для удовольствия», но заметил, что, хотя большинство файлов .csv входят в историю, они будут делать ряд столбцов с январядо декабря, затем еще пара столбцов с января по декабрь и т. д. Это привело к некоторой фрагментации: фактически 70%!В то время для таблицы требовалось 282 МБ дискового пространства.Затем я перестроил таблицу, сократив фрагментацию до 0%, а зарезервированное пространство сократилось до 118 Мб (!).

Для меня это более чем достаточно

  • вряд лиТаблица превзойдет ограничение в 10 ГБ в ближайшее время, особенно если я буду (онлайн) перестраивать его время от времени.
  • загрузка данных происходит достаточно быстро (хотя перезагрузка всего года заняла пару часов)
  • отчеты достаточно быстрые (на данный момент я еще не пытался подключить к нему какие-либо «интерактивные» инструменты отчетности; но для некоторых простых графиков в Excel это работает просто отлично, ИМХО).

FYI: для создания отчетов я создал простую хранимую процедуру, которая выбирает диапазон для заданного набора столбцов;выдает его в временную таблицу, а затем заполняет пробелы, вычисляя NULL-диапазоны, а затем заполняя их значением, которое предшествовало диапазону.Это работает довольно хорошо, хотя получение «первого» значения иногда занимает некоторое время, так как я не могу предсказать, как далеко назад нужно искать последнее значение (иногда его нет).Чтобы обойти это, я добавил еще один процесс, который экстраполирует значения для каждой временной отметки «час».Таким образом, отчет не должен возвращаться более чем на 1 час.Флаг-столбец в таблице показаний указывает, было ли экстраполировано значение в записи для данного поля или нет.(примечание: это делает обновление значений в прошлом более проблематичным, но не невозможным)

Надеюсь, это поможет вам в ваших начинаниях, удачи!

0 голосов
/ 25 декабря 2018

На самом деле, я думаю, у вас есть лучший план.Вы можете использовать временные таблицы из SQL Server 2016. Этот тип, управляемый sql, наилучшим образом отслеживает изменение таблицы.Посетите эту ссылку: https://docs.microsoft.com/en-us/sql/relational-databases/tables/temporal-tables?view=sql-server-2017

...