Сохранение в поток (постановка)

Материал из GedeminWiki
(Различия между версиями)
Перейти к: навигация, поиск
(Уменьшение размера файла)
Строка 5: Строка 5:
 
# Не использовать бизнес-объекты;
 
# Не использовать бизнес-объекты;
 
# Работать только с информацией о метаданных из реляционной БД. Сделать всю информацию, не укладывающуюся в реляционную схему, внешней по относительности к процессу сохранения (см. например, аттрибут "Перезаписывать данными из потока").
 
# Работать только с информацией о метаданных из реляционной БД. Сделать всю информацию, не укладывающуюся в реляционную схему, внешней по относительности к процессу сохранения (см. например, аттрибут "Перезаписывать данными из потока").
 +
# Предусмотреть возможность сохранения только объектов измененных после указанной даты;
 +
# Предусмотреть возможность инкрементного сохранения объектов.
  
 
===Увеличение скорости===
 
===Увеличение скорости===
Строка 13: Строка 15:
 
# создаем клиент датасет и переносим в него данные полей сохраняемой записи;
 
# создаем клиент датасет и переносим в него данные полей сохраняемой записи;
 
# записываем в поток служебную информацию и данные клиент датасета;
 
# записываем в поток служебную информацию и данные клиент датасета;
# находим поля-ссылки, создаем экземпляры бизнес-объектов соответствующего типа и рекурсивно вызываем процедуру сохранения в поток, т.е. переходим к п. 1;
+
# находим поля-ссылки, создаем экземпляры бизнес-объектов соответствующего типа и рекурсивно вызываем процедуру сохранения в поток, т.е. переходим к п. 1.
  
таким образом, в процессе сохранения объект одного и того же типа может создаваться неограниченное число раз.
+
Таким образом, в процессе сохранения объект одного и того же типа может создаваться неограниченное число раз.
  
Итак, первый шаг -- мы отказываемся от рекурсии. А это значит, что мы будем повторно использовать объект одного типа, если ранее уже такой встречался. Точнее, рекурсия все же будет, но при сохранении объекта определенного типа, от которого зависит сохраняемый в данный момент времени объект, мы будем попадать (рекурсивно) в его же код! Следует быть осторожным и контролировать повторное использование ресурсов.
+
Итак, первый шаг -- мы отказываемся от рекурсии и будем повторно использовать объект при необходимости. Второй шаг -- отказаться от использования бизнес-объектов. Поскольку, мы не храним данных в ином месте, кроме как в реляционной базе, следовательно все должно сработать правильно и перенестись на другую базу корректно. Отказавшись от бизнес объектов приходится брать на себя анализ структуры базы данных и по главной таблице бизнес объекта (GetListTable) находить все таблицы связанные связью один-к-одному, а так же таблицы элементов множества.  
  
Второй шаг -- отказаться от использования бизнес-объектов. Поскольку, мы не храним данных в ином месте, кроме как в реляционной базе, следовательно все должно сработать правильно и перенестись на другую базу корректно.  
+
<pre>
 +
Тут возникает интересный момент: у нас, главная таблица для любого документа -- это [[gd_document]], хотя специфические его данные хранятся в присоединенной таблице. При анализе связей таблицы gd_document находим 216 ссылающихся таблиц. Пока не ясно, стоит ли с этим смириться или каким-то образом отсекать таблицы, связанные с gd_document, но не имеющие отношения к типу сохраняемого бизнес-объекта.
 +
</pre>
  
Отказавшись от бизнес объектов приходится брать на себя анализ структуры базы данных и по главной таблице бизнес объекта (GetListTable) находить все таблицы связанные связью один-к-одному, а так же таблицы элементов множества. Тут возникает интересный момент: у нас, главная таблица для любого документа -- это [[gd_document]], хотя специфические его данные хранятся в присоединенной таблице. При анализе связей таблицы gd_document находим 216 ссылающихся таблиц. Пока не ясно, стоит ли с этим смириться или каким-то образом отсекать таблицы, связанные с gd_document, но не имеющие отношения к типу сохраняемого бизнес-объекта.
+
Относительно существующего алгоритма, ускорение можно получить за счет кэширования системной информации о связях таблиц. Сейчас для каждого объекта вычисляется:
 
+
# какие таблицы имеют отношение один-к-одному  к главной таблице;
Кроме того ускорение можно получить за счет кэширования связей таблиц. На данном этапе мы каждый раз вычисляем:
+
# какие таблицы имеют отношение один к одному  к главной таблице;
+
 
# какие таблицы имеют ссылку на главную таблицу с доменом MASTERKEY;
 
# какие таблицы имеют ссылку на главную таблицу с доменом MASTERKEY;
# какие таблицы входят в SELECT-запрос бизнес-объекта;
+
# какие таблицы входят в SELECT-запрос бизнес-объекта.
Имеет смысл производить эти вычисления один раз для каждого класса + сабтайп.
+
 
 +
В новом алгоритме имеет смысл производить эти вычисления один раз для каждого класса + сабтайпа.
  
 
===Уменьшение размера файла===
 
===Уменьшение размера файла===

Версия 19:35, 13 января 2007

Требования к новому сохранению в поток:

  1. Увеличение скорости минимум в 10 раз;
  2. Уменьшение размера файла минимум в 10 раз (при использовании двоичного формата);
  3. Возможность сохранения в формате XML;
  4. Не использовать бизнес-объекты;
  5. Работать только с информацией о метаданных из реляционной БД. Сделать всю информацию, не укладывающуюся в реляционную схему, внешней по относительности к процессу сохранения (см. например, аттрибут "Перезаписывать данными из потока").
  6. Предусмотреть возможность сохранения только объектов измененных после указанной даты;
  7. Предусмотреть возможность инкрементного сохранения объектов.

Увеличение скорости

Беглый анализ показывает, что основной проблемой существующего сохранения является использование рекурсии и бизнес объектов. Сейчас работает так:

  1. начинаем сохранять запись определенного типа (запись бизнес-объекта);
  2. создаем клиент датасет и переносим в него данные полей сохраняемой записи;
  3. записываем в поток служебную информацию и данные клиент датасета;
  4. находим поля-ссылки, создаем экземпляры бизнес-объектов соответствующего типа и рекурсивно вызываем процедуру сохранения в поток, т.е. переходим к п. 1.

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

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

Тут возникает интересный момент: у нас, главная таблица для любого документа -- это [[gd_document]], хотя специфические его данные хранятся в присоединенной таблице. При анализе связей таблицы gd_document находим 216 ссылающихся таблиц. Пока не ясно, стоит ли с этим смириться или каким-то образом отсекать таблицы, связанные с gd_document, но не имеющие отношения к типу сохраняемого бизнес-объекта.

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

  1. какие таблицы имеют отношение один-к-одному к главной таблице;
  2. какие таблицы имеют ссылку на главную таблицу с доменом MASTERKEY;
  3. какие таблицы входят в SELECT-запрос бизнес-объекта.

В новом алгоритме имеет смысл производить эти вычисления один раз для каждого класса + сабтайпа.

Уменьшение размера файла

Уменьшения размера файла мы добьемся за счет отказа от рекурсии при формировании потока данных из-за которой мы имеем следующую внутреннюю структуру файла:

Save stream 1.png

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

Save stream 2.png

Персональные инструменты
Пространства имён

Варианты
Действия
Навигация
Инструменты