Каков наилучший способ хранения и поиска по объектным транзакциям? - PullRequest
3 голосов
/ 06 ноября 2008

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

В настоящее время транзакции хранятся в виде транзакции и набора транзакций LI.

В таблице транзакций есть поля для того, кто, что, когда, почему, foreignKey и foreignTable. Первые четыре говорят сами за себя. ForeignKey и foreignTable используются для определения того, какой объект изменился.

TransactionLI имеет метку времени, ключ, val, oldVal и идентификатор транзакции. В основном это система хранения ключ / значение / oldValue.

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

Итак, мы думаем о других способах сделать что-то подобное. Вещи, которые мы рассмотрели до сих пор: - Раскрытие этих таблиц чем-то вроде отметки времени. - Денормализуем две таблицы и объединяем их в одну. - комбинация из двух выше. - Делать что-то в соответствии с сериализацией каждого объекта после изменения и сохранять его в Subversion. - Возможно, что-то еще, но я не могу думать об этом прямо сейчас.

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

Что все остальные делают?

Ответы [ 4 ]

1 голос
/ 12 декабря 2008

Мы выбрали следующий подход: -

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

  2. Доступ к хранилищу объектов осуществляется через представление SQL. Представление отображает несколько таблиц, которые идентичны по структуре, но к имени таблицы добавлен GUID. Новая таблица создается, когда предыдущая таблица достигла критической массы (предварительно определенное количество строк)

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

  4. Наконец, в рамках процедуры overnight мы архивируем любые старые экземпляры объектов, которые больше не требуются на диск (а затем на ленту).

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

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

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

0 голосов
/ 05 декабря 2008

Если важен запрос данных, я бы использовал истинное разделение в SQL Server 2005 и более поздних версиях, если у вас есть корпоративная версия SQL Server. У нас есть миллионы строк, разбитых по годам в текущем месяце - вы можете быть настолько детализированы, насколько того требует ваше приложение, с максимальным количеством 1000 разделов.

В качестве альтернативы, если вы используете SQL 2008, вы можете посмотреть на отфильтрованные индексы.

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

Разумеется, следует учитывать разбиение / архивирование старых изменений.

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

Я никогда не находил отличного решения всех проблем такого типа. Некоторые вещи, которые вы можете попробовать, - это если ваша БД поддерживает разбиение на разделы (или даже если вы этого не сделаете, вы можете реализовать ту же концепцию самостоятельно), но разделить эту таблицу журналов по типу объекта, а затем вы сможете продолжить разбиение по дате / времени или вашим Идентификатор объекта (если ваш идентификатор числовой, это прекрасно работает, не знаю, как будет разделен guid).

Это поможет сохранить размер таблицы и сохранить все связанные транзакции для одного экземпляра объекта для себя.

Одна из идей, которую вы могли бы изучить, состоит в том, что вместо сохранения каждого поля в таблице пар имя-значение вы можете хранить данные в виде большого двоичного объекта (текстового или двоичного). Например, сериализовать объект в Xml и сохранить его в поле.

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

Я добился огромного успеха, сохранив довольно сложную объектную модель с множеством взаимосвязей в виде большого двоичного объекта (сериализатор xml в .net не обрабатывал отношения между объектами). Я мог очень легко видеть себя хранящим двоичные данные. Огромным недостатком хранения его в виде двоичных данных является то, что для доступа к нему вам нужно вынуть его из базы данных с помощью Xml, если вы используете современную базу данных, такую ​​как MSSQL, вы можете получить доступ к данным.

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

<objectDiff>
<field name="firstName" newValue="Josh" oldValue="joshua"/>
<field name="lastName" newValue="Box" oldValue="boxer"/>
</objectDiff>

Это поможет уменьшить количество строк, и, если вы используете MSSQL, вы можете определить XML-схему и получить некоторые богатые возможности запросов вокруг объекта. Вы все еще можете разделить таблицу.

Josh

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