Я предполагаю, что вы думаете о разреженных матрицах из математического контекста:
http://en.wikipedia.org/wiki/Sparse_matrix (Описанные здесь методы хранения предназначены для хранения в памяти (быстрая арифметическая операция), а не для постоянного хранения (низкое использование диска).)
Так как обычно все работают с этими матрицами на стороне клиента, а не на стороне сервера, SQL-ARRAY [] - лучший выбор!
Вопрос в том, как воспользоваться разреженностью матрицы? Вот результаты некоторых исследований.
Установка:
- Postgres 8,4
- Матрицы с 400 * 400 элементами с двойной точностью (8 байт) -> 1,28 МБ необработанного размера на матрицу
- 33% ненулевых элементов -> эффективный размер 427киБ на матрицу
- усреднено с использованием ~ 1000 различных случайных заполненных матриц
Методы конкуренции:
- Положитесь на автоматическую сторону сервера сжатие столбцов с помощью SET STORAGE MAIN или EXTENDED.
- Храните только ненулевые элементы плюс растровое изображение (
bit varying(xx)
), описывающее, где найти ненулевые элементы в матрице. (Одна двойная точность в 64 раза больше, чем один бит. Теоретически (игнорируя издержки) этот метод должен быть улучшен, если <= 98% отличны от нуля ;-).) Включено сжатие на стороне сервера. </li>
- Заменить нулей в матрице на NULL . (СУБД очень эффективны для хранения значений NULL.) Сжатие на стороне сервера активировано.
(Индексирование ненулевых элементов с использованием 2nd index-ARRAY [] не очень многообещающе и поэтому не проверено.)
Результаты:
- Автоматическое сжатие
- никаких дополнительных усилий по реализации
- нет снижения сетевого трафика
- минимальные накладные расходы на сжатие
- постоянное хранение = 39% от необработанного размера
- Bitmap
- приемлемые усилия по реализации
- сетевой трафик немного уменьшился; зависит от редкости
- постоянное хранение = 33,9% от необработанного размера
- Заменить нули на NULL
- некоторые усилия по реализации (API должен знать, где и как устанавливать значения NULL в ARRAY [] при создании запроса INSERT)
- без изменений в сетевом трафике
- постоянное хранение = 35% от необработанного размера
Вывод:
Начните с параметра EXTENDED / MAIN. Если у вас есть свободное время, изучите ваши данные и используйте мою настройку теста с вашим уровнем разреженности. Но эффект может быть ниже, чем вы ожидаете.
Я предлагаю всегда использовать сериализацию матрицы (например, порядок старших строк) плюс два целочисленных столбца для размеров матрицы NxM. Поскольку большинство API используют текстовый SQL, вы экономите много сетевого трафика и клиентской памяти для вложенных «ARRAY [ARRAY [..], ARRAY [..], ARRAY [..], ARRAY [..], ..]» !!!
Tebas
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;