Если ваша матрица действительно разрежена (то есть узлы имеют только несколько взаимосвязей), то вы получите достаточно эффективное хранилище от СУБД, такой как Oracle, PostgreSQL или SQL Server.По сути, у вас будет таблица с двумя полями (строка, столбец) и индексом или ключом в каждую сторону.
Установите первичный ключ в одну сторону (в зависимости от того, выполняете ли вы в основном запрос по строке или столбцу) и выполнитедругой индекс на полях наоборот.Это будет хранить данные только там, где есть соединение, и оно будет пропорционально количеству ребер на графике.
Индексы позволят вам эффективно извлекать либо строку, либо столбец и всегда будут синхронизированы.
Если у вас есть 10 000 узлов и 10 соединений на узел, в базе данных будет только 100 000 записей.100 ребер на узел будут иметь 1000000 записей и так далее.Для разреженных подключений это должно быть достаточно эффективным.
Оценка пакета с ошибками
Эта таблица, по существу, будет содержать поле строки и столбца.Если кластеризованный индекс идет (строка, столбец, значение), тогда другой покрывающий индекс будет идти (столбец, строка, значение).Если бы добавления и удаления были случайными (т. Е. Не сгруппированы по строкам или столбцам), число операций ввода-вывода было бы приблизительно вдвое больше, чем просто для таблицы.
Если бы вы добавляли вставки по строкам или столбцам, вы получитеменьше операций ввода-вывода по одному из индексов, поскольку записи физически расположены вместе в одном из индексов.Если матрица действительно разрежена, то это представление списка смежности является, безусловно, самым компактным способом его хранения, который будет намного быстрее, чем сохранение его в виде двумерного массива.
Матрица 10 000 x 10 000 с 64-битнойзначение займет 800 МБ плюс индекс строки.Обновление одного значения потребовало бы записи по крайней мере 80 КБ для каждой записи (выписывание всей строки).Вы можете оптимизировать записи по строкам, если ваши данные могут быть сгруппированы по строкам на вставках.Если вставки выполняются в реальном времени и случайным образом, то для каждой вставки вы будете записывать по 80 тыс. Строк.
На практике эти записи будут иметь некоторую эффективность, поскольку все они будут записываться в непрерывной области, в зависимости откак ваша платформа NoSQL физически хранила свои данные.
Я не знаю, насколько скудна ваша связь, но если бы у каждого узла было в среднем 100 соединений, то у вас было бы 1 000 000 записей.Это будет примерно 16 байт на строку (строка Int4, столбец Int4, значение Double) плюс несколько байтов для кластерной таблицы и индекса покрытия.Эта структура заняла бы около 32 МБ + немного накладных расходов на хранение.
Обновление одной записи в строке или столбце приведет к двум операциям записи в один диск (8 КБ, на практике сегмент) для произвольного доступа, при условии, что вставки не упорядочены по строке или столбцу.
Добавление 1 миллиона случайно упорядоченных записей в представление массива приведет к примерно 80 ГБ операций записи + небольшие накладные расходы.Добавление 1м записей в представление списка смежности приведет к записи приблизительно 32 МБ (на практике 16 ГБ, поскольку весь блок будет записан для каждого конечного узла индекса), а также к небольшим накладным расходам.
Для этого уровня подключения (10000 узлов, 100 ребер на узел) список смежности будет более эффективным в пространстве памяти, а также, вероятно, и в операциях ввода-вывода.Вы получите некоторую оптимизацию от платформы, так что какой-то эталонный тест может быть уместным, чтобы увидеть, что быстрее на практике.