Можно ли в mysql хранить 200 колонок, для 10+млн записей?
Вопрос в том как это повлияет на скорость и много ли потребуется памяти для запроса.
Имеются метрики A, B, C их около 200 штук, с числовыми значениями, их нужно хранить хранить в ненормальной форме в виде колонок или в массиве: [ {a: 1, b: 7, c: 9} ] или [1, 7, 9, ...] с последующим подсчетом суммы каждой метрики в запросе. Например, есть строки вида
ключевое слово 1 | site 1 | [5, 7, 9, ...]
ключевое слово 1 | site 2 | [1, 3, 2, ...]
нужно сгруппировать ключевое слово, и подсчитать количество метрик, должно быть так
ключевое слово 1 | [6, 10, 11, ...]
Akina, пока другого решения не нашел. это нужно для выборки разом топ 10 ключевых слов с метриками Таблица
name | rating | siteId | region | + 4 фильтра
SELECT name, SUM(rating), SUM(метрики) FROM table GROUP BY `name` ... limit 10;
если делать отдельную таблицу для метрик и делать джоин, то `rating` увеличивается в зависимости от строк правой таблицы, отчего топ будет неправильный
- идентификатор объекта
- идентификатор метрики
- значение метрики
Таблица
name | rating | siteId | region | + 4 фильтра
Как это соотносится со структурой, показанной в вопросе?
если делать отдельную таблицу для метрик и делать джоин, то `rating` увеличивается в зависимости от строк правой таблицы, отчего топ будет неправильный
Неправильный запрос даёт неправильный результат - что тут странного? составьте правильный запрос.
Как это соотносится со структурой, показанной в вопросе?
в вопросе привел упрощенный пример того что есть, и задал вопрос, возможно ли хранить и обрабатывать 200+ колонок для записей больше 10млн. Так как хотел, чтоб не было заморочек с пониманием вопроса и ответом. Поэтому на ваш вопрос ответил уже с почти полной структурой, чтоб было понимание почему так сделано.
Неправильный запрос даёт неправильный результат - что тут странного? составьте правильный запрос.
правильный запрос будет содержать вложенный select с перебором десятков тысяч строк, поэтому хотелось бы чтоб был один запрос, который будет группировать ключевые слова по названию(по id названия), суммировать рейтинги, и 200+ метрик, фильтровать при необходимости по нескольким параметрам и сортировать по сумме рейтинга для вывода топ 10 ключевых слов.
правильный запрос будет содержать вложенный select с перебором десятков тысяч строк
Это зачем, спрашивается? Как-то описание задачи ну совсем не тянет на подзапросы.
Вы бы показали пример данных - CREATE TABLE, оставить только 3-4 поля с метриками, INSERT INTO, с десяток записей, и значения только для оставленных метрик, требуемый результат для этих данных, ну и пояснения, как и почему посчитаны те или иные итоги.
Для правильного вопроса надо знать половину ответа
Смотрим здесь. Получаем для обычного INT 4 байта на одно число, для BIGINT 8 байт.
200 * 4 * 10'000'000 = 8'000'000'000 или 8Gb.
200 * 8 * 10'000'000 = 16'000'000'000 или 16Gb.
По нынешним меркам сущие пустяки.
Хранить, конечно же, нужно в нормальной форме, иначе суммирование придётся делать в приложении.
Иерокопус Таманский, Да вопрос в общем в этом. но пока как возможное решение пришел к паре сотен колонок, для того чтобы в одной выборке получить и топ 10 ключевых слов, и метрики. не усложняя запрос джоинами и вложенными запросами
Да, для хранения, добавления и чтения данных с анализом этот подход очень хорош, ценой незначительного для твоих объемов (кратного, Rsa97 все расписал) ты получишь огромный прирост производительности. Настоятельно рекомендую протестировать на тестовом стенде на своих данных, особенность хранения null записей в innodb и работа индесов с ними. Что лучше в твоем случае парный индекс в денормализованной форме или 200 индексов в нормальной можно будет определить только тестами (большая таблица может потребовать больше оперативной памяти на индексы).
Есть еще недостаток - если в таблице будет очень много данных, добавление и тем более удаление колонки будет проходить очень медленно, особенно если база данных в это время будет использоваться.