Предполагам, че мислите за разредени матрици от математически контекст:http://en.wikipedia. org/wiki/Sparse_matrix (Техниките за съхранение, описани там, са за съхранение в памет (бърза аритметична операция), а не за постоянно съхранение (ниско използване на диска).)
Тъй като обикновено се работи с тези матрици от страна на клиента, а не от страна на сървъра, SQL-ARRAY[] е най-добрият избор!
Въпросът е как да се възползваме от разредността на матрицата? Ето резултатите от някои разследвания.
Настройка:
- Postgres 8.4
- Матрици с 400*400 елемента с двойна точност (8 байта) --> 1,28 MiB необработен размер на матрица
- 33% ненулеви елементи --> 427 kiB ефективен размер на матрица
- осреднено с помощта на ~1000 различни произволно попълнени матрици
Конкурентни методи:
- Разчитайте на автоматично компресия от страна на сървъра от колони с SET STORAGE MAIN или EXTENDED.
- Съхранявайте само ненулевите елементи плюс растерно изображение (
bit varying(xx)
), описващи къде да се намират ненулевите елементи в матрицата. (Една двойна точност е 64 пъти по-голяма от един бит. На теория (пренебрегвайки режийните разходи) този метод би трябвало да е подобрение, ако <=98% са различни от нула;-).) Компресията от страна на сървъра е активирана. - Замяна нулите в матрицата с NULL . (RDBMS са много ефективни при съхраняване на NULL.) Компресията от страна на сървъра е активирана.
(Индексирането на ненулеви елементи с помощта на 2-ри индекс-ARRAY[] не е много обещаващо и поради това не е тествано.)
Резултати:
- Автоматично компресиране
- без допълнителни усилия за внедряване
- без намален мрежов трафик
- минимални разходи за компресия
- постоянно хранилище =39% от необработения размер
- Растерно изображение
- приемливи усилия за внедряване
- мрежовият трафик леко намаля; в зависимост от разрядността
- постоянно хранилище =33,9% от необработения размер
- Заменете нули с NULL
- известни усилия за внедряване (API трябва да знае къде и как да зададе NULL в ARRAY[], докато конструира заявката INSERT)
- няма промяна в мрежовия трафик
- постоянно хранилище =35% от необработения размер
Заключение:Започнете с параметъра РАЗШИРЕНО/ОСНОВНО съхранение. Ако имате малко свободно време, проучете вашите данни и използвайте моята тестова настройка с вашето ниво на разреденост. Но ефектът може да е по-малък от очаквания.
Предлагам винаги да се използва сериализацията на матрицата (напр. ред на главния ред) плюс две цели числа за размерите на матрицата NxM. Тъй като повечето API използват текстов SQL, вие спестявате много мрежов трафик и клиентска памет за вложени "МАСИВ[МАСИВ[..], МАСОВ[..], МАСОВ[..], МАСОВ[..], ..]" !!!
Тебас
CREATE TABLE _testschema.matrix_dense
(
matdata double precision[]
);
ALTER TABLE _testschema.matrix_dense ALTER COLUMN matdata SET STORAGE EXTERN;
CREATE TABLE _testschema.matrix_sparse_autocompressed
(
matdata double precision[]
);
CREATE TABLE _testschema.matrix_sparse_bitmap
(
matdata double precision[]
bitmap bit varying(8000000)
);
Вмъкнете едни и същи матрици във всички таблици. Конкретните данни зависят от конкретната таблица. Не променяйте данните от страната на сървъра поради неизползвани, но разпределени страници. Или направете ВАКУУМ.
SELECT
pg_total_relation_size('_testschema.matrix_dense') AS dense,
pg_total_relation_size('_testschema.matrix_sparse_autocompressed') AS autocompressed,
pg_total_relation_size('_testschema.matrix_sparse_bitmap') AS bitmap;