Хранение массива в BLOB-поле

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

Var
  aData: Array of Integer;

Процедура записи динамического массива в базу данных получилась примерно такая:

Var
  ms: TMemoryStream;
  …
begin
  …
  Try
    ms := TMemoryStream.Create;
    // Запись содержимого массива aData в поток ms
    ms.WriteBuffer(aData[0], Length(aData) * SizeOf(aData[0]));
    // Запись содержимого потока ms в параметр query для вставки данных
    qInsertResearch.Params[5].LoadFromStream(ms, ftBlob);
  Finally
    ms.Free;
  End;
  …

А процедура чтения массива из базы данных не сложнее процедуры записи:

Var
  ms: TMemoryStream;
  …
begin
  …
  Try
    ms := TMemoryStream.Create;
    // Запись содержимого поля qResearchDATA типа TBlobField в поток ms
    qResearchDATA.SaveToStream(ms);
    // Установка размера динамического массива aData
    SetLength(aData, ms.Size div SizeOf(aData[0]));
    ms.Position := 0;
    // Запись содержимого потока ms в массив aData
    ms.ReadBuffer(aData[0], ms.Size);
  Finally
    ms.Free;
  End;
  …

Теперь на запись/чтение нескольких миллионов записей моя программа тратит секунду. Вместо размера первого элемента массива SizeOf(aData[0]) вы можете использовать размер типа элементов массива (для приведенного мной примера — SizeOf(Integer)). Но такой вариант кода будет менее универсальным, т.к. будет зависеть от используемого типа данных.

P.S. При использовании такого способа хранения данных не забывайте, что размер некоторых типов данных зависит от операционной системы, для которой скомпилирована программа. Иначе информация, которую прочтет из базы данных ваша 64-битная программа перекомпилированная из 32-битной, вас неприятно удивит.

Продолжение…

Читать на сайте автора.