Хранение массива 100k на 100k в MySQL

Мне нужно хранить массивный квадратный массив фиксированного размера в MySQL. Значения массива - это просто INT, но к ним нужно обращаться и изменять их довольно быстро.

Итак, вот что я думаю:

  • Просто используйте 1 столбец для первичных ключей и переведите индексы двухмерных массивов в одномерные индексы. Итак, если массив 2d равен n на n => 2dArray[i][j] = 1dArray[n*(i-1)+j]

Это переводит проблему в хранение массивного одномерного массива в базе данных.

  • Затем используйте другой столбец для значений.

  • Сделайте каждую запись в массиве строкой.

Однако я не очень хорошо знаком с внутренней работой MySQL.

100 КБ * 100 КБ дает 10 миллиардов точек данных, что больше, чем могут дать 32 бита, поэтому я не могу использовать INT в качестве первичного ключа. И исследуя stackoverflow, некоторые люди столкнулись с проблемами производительности при использовании BIGINT в качестве первичного ключа.

В этом случае, когда я храню только INT, упадет ли производительность MySQL по мере увеличения количества строк?

Или, если бы я разбросал данные по нескольким таблицам на одном сервере, могло бы это улучшить производительность? Сейчас похоже, что у меня не будет доступа к нескольким машинам, поэтому я не могу кластеризовать данные.

Я абсолютно гибко отношусь к каждой идее, которую я перечислил выше, и открыт для предложений (кроме того, что я не использую MySQL, потому что я как бы привержен этому!)


person Sarp    schedule 10.06.2017    source источник
comment
У вас есть только один первичный ключ на строку. Поэтому, если у вас всего 100 000 строк, вы можете легко использовать первичный ключ INT. Можете ли вы показать образец набора данных? Как вы будете запрашивать данные?   -  person Aaron J Spetner    schedule 11.06.2017
comment
Одна строка из 100 тыс. столбцов выглядит неуклюже. Я бы пошел на компромисс и разделил каждую строку массива на 1000 строк mysql. В итоге вы получите 100 миллионов строк sql, что выполнимо и требует только 32-битных ключей.   -  person LSerni    schedule 11.06.2017
comment
Одна вещь, которую вы захотите рассмотреть, — это какой формат таблицы использовать. MyISAM будет иметь преимущества в производительности в вашем сценарии.   -  person LSerni    schedule 11.06.2017
comment
Я видел большое количество сообщений, обсуждающих проблемы с производительностью при наличии 100 столбцов, поэтому я просто предположил, что 100 тыс. столбцов будет невозможно. @LSerni Я запутался в том, что вы предложили. Вы имели в виду 1000 столбцов MySQL?   -  person Sarp    schedule 11.06.2017
comment
Нет, я имею в виду, что вы храните каждый 100 000 1D-массив не в 100 000 строк с одним значением столбца или в одной строке со 100 000 значений, а в 1000 строк по 100 значений в каждой. Или, в зависимости от вашего шаблона обновления, может быть 10000 строк по 10 значений в каждой. Всего у вас есть 1000 * 100 тыс. = 100 млн строк или 10000 * 100 тыс. = 1 миллиард строк.   -  person LSerni    schedule 11.06.2017
comment
Это плохой совет использовать MyISAM. Этот механизм хранения постепенно прекращается, поэтому его использование почти всегда является неправильной идеей.   -  person Bill Karwin    schedule 11.06.2017
comment
Не могли бы вы рассказать подробнее о проекте? То, что вы написали, можно реализовать бесконечным количеством способов. Например, мы даже не знаем, можно ли использовать разреженную матричную структуру или нет.   -  person Crouching Kitten    schedule 11.06.2017


Ответы (1)


Что касается вашего беспокойства о том, что BIGINT или добавление большего количества строк снижает производительность, конечно, это правда. У вас будет 10 миллиардов строк, для этого потребуется большая таблица и много оперативной памяти. Потребуется некоторое внимание к запросам, которые вам нужно выполнить для этого набора данных, чтобы выбрать лучший метод хранения.

Вероятно, я рекомендую использовать два столбца для первичного ключа. Разработчики часто упускают из виду возможность использования составного первичного ключа.

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

CREATE TABLE MyTable (
  array_index1 INT NOT NULL,
  array_index1 INT NOT NULL,
  datum WHATEVER_TYPE NOT NULL,
  PRIMARY KEY (array_index1, array_index2)
);

Обратите внимание, что составной индекс, подобный этому, означает, что если вы выполняете поиск во втором столбце без условия равенства в первом столбце, поиск не будет использовать индекс. Поэтому вам нужен вторичный индекс, если вы хотите это поддерживать.

100 000 столбцов не поддерживаются MySQL. MySQL имеет ограничения в 4096 столбцов и 65 535 байт на строку (не считая столбцов BLOB/TEXT).

Хранение данных в нескольких таблицах возможно, но это, вероятно, сделает ваши запросы ужасно неудобными.

Вы также можете изучить таблицу PARTITIONING, но это не так полезно, как кажется.

person Bill Karwin    schedule 10.06.2017
comment
Спасибо за ответ! Но почему большая база данных требует больше памяти, если я правильно структурирую свои SQL-запросы? Разве весь смысл использования базы данных не в том, что она не требует памяти? - person Sarp; 11.06.2017
comment
Извлечение данных из пула буферов (ОЗУ) выполняется на несколько порядков быстрее, чем извлечение с диска. Вы хотите, чтобы ваши наиболее часто запрашиваемые данные находились в пуле буферов. Вам не нужно, чтобы вся база данных находилась в оперативной памяти, но горячие данные должны быть. Мы предполагаем, что в большей базе данных горячая часть также больше. Таким образом, мы выигрываем от большего количества оперативной памяти. - person Bill Karwin; 11.06.2017