Как сохранить данные журнала событий в базе данных? - PullRequest
2 голосов
/ 22 мая 2009

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

Это решило бы многие проблемы для меня, но я не знаю, как сохранить объекты событий в БД. У меня, вероятно, будут сотни типов событий, поэтому у меня ограниченные возможности:

  • построить таблицу для каждого типа события (сотни таблиц? Как насчет ссылок на сущности?)
  • построить огромную таблицу для всех событий (с тысячами столбцов?)
  • каким-то образом хранить двоичное представление события в db (??)
  • сохранить его в отдельном файле (??)

У вас есть идеи, как это можно сделать?

Ответы [ 3 ]

5 голосов
/ 22 мая 2009

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

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

  2. Вы можете придерживаться модели OO и использовать все, что угодно для хранения.

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

СУБД - это один из вариантов, хотя ваша схема будет довольно нереляционной, и вы не сможете воспользоваться некоторыми из мощных реляционных инструментов, которые предлагает вам СУБД. Я бы не стал расстраиваться из-за этого: если вы рассматривали обе модели и решили пойти вразнос, вы сделали этот выбор осознанно. Скорее всего, ваша схема может выглядеть как таблица событий, каждое с именем типа и таблица свойств для каждого события в форме ключ-значение.

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

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

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

Как только вы все равно сериализуетесь, у вас есть множество других возможностей для хранения. Вы также можете хранить свой сериализованный кусок в БД Berkeley или столбце в СУБД.

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

InvoiceCreate invoice_number=12345 date=2009-05-21 salesperson="Jill Gaines" ...

Это имеет много преимуществ:

  • Он удобочитаем, поэтому его легко отлаживать.
  • Такие файлы можно обрабатывать с помощью grep, sed, awk и т. Д. Для специальных запросов.
  • Это доступно для записи человеком, что хорошо для отладки, тестирования и исправления поврежденных данных.
  • Это легко разобрать.
  • Он не связан с какой-либо конкретной структурой объекта, форматом или даже языком, поэтому вы можете легко изменить свое приложение, не беспокоясь о совместимости с вашими сериализованными данными.
  • Сами данные могут быть легко обновлены (часто с помощью простого сценария sed!), Когда вам нужно изменить формат данных.

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

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

Это также может быть использовано в качестве точки продажи для этого: если вы в конечном итоге возражаете против того, что вы не используете СУБД (нужна вам это или нет), просто продайте это как «фазу эксперимента», пока вы работаете модель и скажите им, что вы двигаетесь, как только модель успокоится. Даже если она не сдвинется с места, когда у вас будет хорошо работающая система, они вряд ли окажут на вас большое давление.

1 голос
/ 22 мая 2009

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

Я довольно часто использовал этот шаблон, и обычно это набор (не слишком много) таблиц с минимальным первичным ключом для таблицы, отметкой времени и именем пользователя.

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

Пара преимуществ -

  1. Это хороший хук для взаимодействия с пользователем для вашего дизайна, потому что это одна из немногих таблиц в вашей базе данных, которая самоочевидна. («Да, это то, что люди делают, и что нужно записывать, когда они это делают».)

  2. Он обеспечивает некоторую практическую гибкость при работе с транзакциями из нескольких источников, которые могут быть не интегрированы в режиме реального времени, но вам необходимо восстановить хронологию. (Например, доставка из пункта A через B и C в D).

0 голосов
/ 22 мая 2009

другой вариант - сохранить соответствующие ключи и общие значения поиска в обычных столбцах и поместить остальные в столбец XML (или эквивалентный форматированный текст, например, JSON или любой другой, подходящий для вашего приложения)

это предполагает, что большую часть времени все, что вам нужно сделать, это восстановить исходное событие из базы данных (например, сериализация / десериализация), а не искать (эффективно) каждое возможное свойство

...