Нормализация данных временного ряда
Я создаю базу данных для хранения большого количества событий. Их будет много, и у каждого из них будет ассоциированное время с точностью до секунды. Как пример, что-то вроде этого:
Event
-----
Timestamp
ActionType (FK)
Source (FK)
Target (FK)
Действия, источники и цели все в 6NF. Я хотел бы сохранить Event
таблица нормализовалась, но у всех подходов, которые я мог придумать, есть проблемы. Чтобы быть уверенным в моих ожиданиях в отношении данных, подавляющее большинство (99,9%) событий будут уникальными только с четырьмя вышеуказанными полями (поэтому я могу использовать всю строку в качестве PK), но некоторые исключения нельзя игнорировать,
Используйте суррогатный ключ: если я использую четырехбайтовое целое число, это возможно, но похоже, что просто надувать таблицу без причины. Кроме того, я обеспокоен использованием базы данных в течение длительного периода времени и исчерпанием пространства ключей.
Добавление столбца количества к событию: так как я ожидаю небольших подсчетов, я мог бы использовать меньший тип данных, и это оказало бы меньшее влияние на размер базы данных, но для вставки перед загрузкой потребовались бы дополнительные операции или объединение данных вне базы данных. Любое из них добавило бы сложности и повлияло бы на мой выбор программного обеспечения для баз данных (я думал о том, чтобы пойти с Postgres, который делает упор, но не с удовольствием.)
Разбить события на небольшие группы: например, все события в одну секунду могут быть частью
Bundle
который может иметь суррогатный ключ для группы и другой для каждого события внутри него. Это добавляет еще один уровень абстракции и размер в базу данных. Было бы неплохо, если бы повторяющиеся события стали обычным явлением, но в остальном это кажется излишним.
Хотя все это выполнимо, они плохо подходят для моих данных. Я думал просто сделать типичную Снежинку и не применять ограничение уникальности на главной Event
Таблица, но после прочтения ответов PerformanceDBA, как этот, я подумал, может быть, есть лучший способ.
Итак, как правильно сохранить данные временных рядов с небольшим числом повторяющихся событий?
Изменить: Уточнение - источником данных являются журналы, в основном плоские файлы, но некоторые в различных базах данных. Одна из целей этой базы данных - объединить их. Ни один из источников не имеет временного разрешения более точного, чем второй. Эти данные будут использоваться для вопросов типа "Сколько разных источников выполнили действие на цели за интервал?" где Интервал будет не менее часа.
1 ответ
Самые простые ответы кажутся
- сохранить метку времени с большей точностью, или
- сохраните метку времени до второй и повторите попытку (с чуть более поздней меткой времени), если INSERT завершится неудачно из-за дублированного ключа.
Ни одна из трех упомянутых вами идей не имеет ничего общего с нормализацией. Это решения о том, что хранить; на концептуальном уровне вы нормализуетесь после того, как решите, что хранить. Что означает строка (значит, что означает каждый столбец); эти значения составляют предикат таблицы. Предикат позволяет вам получать новые правдивые факты из старых правдивых фактов.
Используя целое число в качестве суррогатного ключа, вы вряд ли исчерпаете пространство ключей. Но вы все равно должны объявить естественный ключ, поэтому суррогат в этом случае не сделает для вас ничего полезного.
Добавление столбца "считать" имеет смысл, если имеет смысл считать вещи; в противном случае это не так. Посмотрите на эти два примера.
Timestamp ActionType Source Target
--
2013-02-02 08:00:01 Wibble SysA SysB
2013-02-02 08:00:02 Wibble SysA SysB
Timestamp ActionType Source Target Count
--
2013-02-02 08:00:01 Wibble SysA SysB 2
Какая разница в значении здесь? Значение "Метка времени" особенно важно. Нормализация основана на семантике; что вам нужно сделать, зависит от того, что означают данные, а не от того, как называются столбцы.
Разделение событий на небольшие группы может иметь смысл (например, добавление столбца "count" может иметь смысл), если группы событий имеют значение в вашей системе.