2008-11-06 5 views
3

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

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

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

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

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

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

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

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

+0

какая у вас база данных? вы можете исследовать отслеживание изменений SQL в SQL 2008. Он не отслеживает ваши объекты, но будет отслеживать ваши изменения данных и их версию. – D3vtr0n 2008-12-04 02:14:23

ответ

0

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

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

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

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

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

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

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

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

Джош

0

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

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

0

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

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

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

Должны быть рассмотрены более ранние изменения разделов/архивирования.

1

Мы приняли следующий подход: -

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

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

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

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