Код ошибки 1117 Слишком много столбцов; MySQL столбец-предел в таблице


37

У меня есть таблица с 1699 столбцами, и когда я пытаюсь вставить больше столбцов, я получаю,

Код ошибки: 1117. Слишком много столбцов

В этой таблице у меня только 1000 строк. Для меня самое главное это количество столбцов. Есть ли ограничения на стол? Я хочу создать 2000 столбцов. Это возможно?


22
Господи, какого черта. Это пахнет безумно плохим дизайном базы данных. Или, возможно, вы используете не тот инструмент для работы. Возможно, вы должны смотреть на нормализацию базы данных
Zoredache

12
Поверните монитор на 90 градусов. Более серьезно, MySQL (или почти любая другая СУБД) не предназначена для ТОГО многих столбцов.

11
И почему 2000 датчиков должны приводить к 2000 столбцам? Редизайн вашей базы данных. Создайте отдельную таблицу датчиков или что-то, но НЕ добавляйте каждый датчик в качестве нового столбца. Это просто невероятно неправильно.

6
Максимальное количество столов ... стой! Скорее всего, вам понадобится всего пара столов. Даже не думайте создавать 2000 таблиц вместо 2000 столбцов!

2
Пожалуйста, пожалуйста, прочитайте о нормализации базы данных !

Ответы:


35

Зачем вам нужно создавать таблицу даже с 20 столбцами, не говоря уже о 2000 ???

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

Если таблица столбцов 2000 подвергается SELECT * FROM ... WHERE, вы будете генерировать большие временные таблицы во время обработки, извлекать ненужные столбцы и создавать множество сценариев, в которых пакеты связи ( max_allowed_packet ) будут отправляться на грань при каждом запросе.

В начале своей работы в качестве разработчика я работал в компании в 1995 году, где DB2 была основной СУБД. У компании была одна таблица с 270 столбцами, десятками индексов и проблемами с производительностью при получении данных. Они связались с IBM и попросили консультантов просмотреть архитектуру их системы, включая эту единственную монолитную таблицу. Компании сказали: «Если вы не нормализуете эту таблицу в течение следующих 2 лет, DB2 не сможет выполнить запросы, выполняющие обработку на этапе 2 (любые запросы, требующие сортировки по неиндексированным столбцам)». Это было сказано мульти-триллионной компании, чтобы нормализовать таблицу из 270 столбцов. Насколько тем более таблица 2000 столбцов.

С точки зрения mysql вам придется компенсировать такой плохой дизайн, устанавливая параметры, сравнимые с DB2 Stage2 Processing. В этом случае эти варианты будут

Изменение этих настроек, чтобы компенсировать наличие десятков, не говоря уже о сотнях столбцов, работает хорошо, если у вас есть ТБ ОЗУ.

Эта проблема геометрически умножается, если вы используете InnoDB, поскольку вам придется иметь дело с MVCC (Multiversion Concurrency Control), пытающимся защитить тонны столбцов с каждым SELECT, UPDATE и DELETE посредством изоляции транзакции.

ВЫВОД

Там нет замены или лейкопластырь, который может восполнить плохой дизайн. Пожалуйста, ради вашего здравомыслия в будущем, нормализуйте этот стол сегодня !!!


1
Я мог представить, как компания поступит, когда скажет это. Они добавляют svn-хуки или создают «Руководства по оптимальным методам работы с БД», предлагая разработчикам не сортировать неиндексированные столбцы в SQL. Вместо этого они выполняют сортировку в приложении, реализуя собственный алгоритм сортировки больших данных.
Gqqnbig

25

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

Я предполагаю, что вы, вероятно, делаете какую-то денормализованную схему «заполнить пробелы», где вы фактически храните все различные виды данных в одной таблице, а не разбиваете данные на отдельные таблицы и создаете отношения у вас есть различные поля, которые записывают, какой «тип» данных хранится в данной строке, и 90% ваших полей имеют значение NULL. Даже тогда, хотя, чтобы хотеть добраться до 2000 колонок ... yikes.

Решение вашей проблемы - переосмыслить модель данных. Если вы храните большую кучу данных ключ / значение, связанных с данной записью, почему бы не смоделировать ее таким образом? Что-то типа:

CREATE TABLE master (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields that really do relate to the
    master records on a 1-to-1 basis>
);

CREATE TABLE sensor_readings (
    id INT PRIMARY KEY AUTO_INCREMENT,
    master_id INT NOT NULL,   -- The id of the record in the
                              -- master table this field belongs to
    sensor_id INT NOT NULL,
    value VARCHAR(255)
);

CREATE TABLE sensors (
    id INT PRIMARY KEY AUTO_INCREMENT,
    <fields relating to sensors>
);

Затем получить все записи датчика, связанные с данной «основной» записью, можно просто SELECT sensor_id,value FROM sensor_readings WHERE master_id=<some master ID>. Если вам нужно получить данные для записи в masterтаблице вместе со всеми данными датчика для этой записи, вы можете использовать объединение:

SELECT master.*,sensor_readings.sensor_id,sensor_readings.value
FROM master INNER JOIN sensor_readings on master.id=sensor_readings.master_id
WHERE master.id=<some ID>

И затем присоединяется, если вам нужны подробности о том, что представляет собой каждый датчик.


18

Это измерительная система с 2000 датчиков

Игнорируйте все комментарии, кричащие о нормализации - то, что вы просите, может быть разумным дизайном базы данных (в идеальном мире) и совершенно хорошо нормализовано, это просто очень необычно, и, как указывалось в других местах, СУБД обычно просто не предназначены для такого количества столбцов ,

Хотя вы не достигаете жесткого ограничения MySQL , один из других факторов, упомянутых в ссылке, вероятно, мешает вам подняться выше.

Как предлагают другие, вы могли бы обойти это ограничение, имея дочернюю таблицу id, sensor_id, sensor_valueили, проще говоря, вы могли бы создать вторую таблицу, содержащую только столбцы, которые не будут помещаться в первую (и использовать тот же PK)


1
Это правда. При тщательной обработке данных и соответствующего SQL ваш ответ выделяется еще больше !!!
RolandoMySQLDBA

3
Использование дочерней таблицы не является «обходным путем». Наличие одного столбца для каждого датчика - просто плохой (неправильный) дизайн. Это похоже на наличие одного столбца для каждого сотрудника в системе управления персоналом или один столбец для каждого производителя автомобилей для БД, которая управляет моделями автомобилей.
a_horse_with_no_name

11
@a_horse - вы делаете предположения, которые, я сомневаюсь, действительны. Вполне возможно, что количество датчиков в основном фиксировано, что все считываются одновременно и что все данные возвращаются каждый раз. В этом случае один столбец на датчик не является «неправильным», просто нецелесообразным, учитывая ограничения базы данных. Я хотел бы предположить, что спрашивающие не идиоты, пока не доказано обратное, и iUngi достойно ответил на них очень бесполезными ответами из SF-толпы.
Джек Дуглас

2
@ Джек Дуглас: даже если бы все ваши предположения были верны (в чем я очень сомневаюсь), сохранение каждого значения датчика в его собственном столбце вызовет проблемы в долгосрочной перспективе. А как насчет запросов типа «каково среднее значение для датчиков от 10 до 50 и от 25 до 100 между вчера и сегодня»? или «Какой датчик имел наибольшее значение показания в прошлый понедельник?». Попробуйте написать запросы для этого с 2000 столбцами. Использование нормализованной таблицы в конечном итоге решит больше проблем, чем решение 2000 столбцов.
a_horse_with_no_name

2
Конечно, если датчики хранят связанные значения - я предполагаю, что они не связаны (например, они все измеряют разные виды вещей, а не в основном одни и те же вещи в разных местах). Вы можете сомневаться в этом, но только ОП знает наверняка - и это не невозможно в медицинской или научной областях.
Джек Дуглас

15

Ограничения на количество столбцов в MySQL 5.0 (выделение добавлено):

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

  • Каждая таблица (независимо от механизма хранения) имеет максимальный размер строки 65 535 байт. Механизмы хранения могут накладывать дополнительные ограничения на этот предел, уменьшая эффективный максимальный размер строки.

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

...

Отдельные механизмы хранения могут накладывать дополнительные ограничения, ограничивающие количество столбцов таблицы. Примеры:

  • InnoDB разрешает до 1000 столбцов.

7

Сначала еще пламенный, потом реальное решение ...

Я в основном согласен с пламенем, уже брошенным на тебя.

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

Один «простой» способ избежать непосредственной проблемы (ограничение количества столбцов) - это «вертикальное разбиение» данных. Скажем, 5 таблиц по 400 столбцов в каждой. Все они будут иметь один и тот же первичный ключ, за исключением того, что у него может быть AUTO_INCREMENT.

Возможно, лучше было бы определиться с дюжиной полей, которые наиболее важны, и поместить их в «основную» таблицу. Затем логически сгруппируйте датчики и разместите их в несколько параллельных таблиц. При правильной группировке вам, возможно, не придется все время присоединяться ко всем таблицам.

Индексируете ли вы какие-либо значения? Вам нужно искать по ним? Возможно, вы ищете на datetime?

Если вам нужно проиндексировать много столбцов - punt.

Если вам нужно проиндексировать несколько - поместите их в основную таблицу.

Вот реальное решение (если оно применимо) ...

Если вам не нужно индексировать огромное количество датчиков, не создавайте столбцы! Да, вы слышали меня. Вместо этого соберите их в JSON, сожмите JSON, сохраните в поле BLOB. Вы сэкономите массу места; у вас будет только одна таблица без проблем с ограничением столбцов; и т. д. Ваше приложение будет распаковано, а затем будет использовать JSON в качестве структуры. Угадай, что? Вы можете иметь структуру - вы можете сгруппировать датчики в массивы, многоуровневые элементы и т. Д., Как бы хотелось ваше приложение. Еще одна «фича» - это открытый. Если вы добавите больше датчиков, вам не нужно изменять таблицу. JSON, если гибкий таким образом.

(Сжатие необязательно; если ваш набор данных огромен, он поможет с дисковым пространством, а следовательно, и общей производительностью.)


Это самый лучший ответ. Можно прокомментировать, что, возможно, ему следует исследовать не столько столбцов, но чтобы принятый ответ «не делай этого» не отвечает на вопрос. Даже если этому парню на самом деле не нужно столько столбцов, возможно, кому-то другому, находящему этот Q, действительно нужно такое количество, и ему нужен реальный ответ.
BoB3K

@ BoB3K - Мой большой абзац говорит, что делать , учитывая доступную информацию о проблеме, как указано. JSONизбегает «слишком много столбцов»; Индексирование выбранных столбцов помогает с производительностью.
Рик Джеймс

3

Я рассматриваю это как возможный сценарий в мире больших данных, где вы, возможно, не выполняете традиционный тип запросов select *. Мы имеем дело с этим в мире прогнозного моделирования на уровне клиента, где мы моделируем клиента по тысячам измерений (все они имеют значения 0 или 1). Этот способ хранения упрощает последующие действия по построению модели и т. Д., Когда у вас есть факторы риска в одной строке и флаг результата в той же строке. Это можно нормализовать с точки зрения хранения с родительской дочерней структурой, но прогнозирующая модель вниз по течению должна будет преобразовать ее обратно в плоскую схему. Мы используем redshift, который хранит столбцы, поэтому ваши 1000+ столбцов, когда вы загружаете данные, на самом деле хранятся в столбчатом формате ...

Есть время и место для этого дизайна. Абсолютно. Нормализация не является решением для каждой проблемы.


Спасибо за комментарий. Если кто-то хочет проводить аналитику с изображениями, даже для небольшого цветного изображения 16x16 пикселей требуется 16 * 16 * 3 целых числа от 0 до 255 (3 числа для описания цвета в одном из 16x16 пикселей с использованием цветов RGB). Это 768 столбцов только для данных, к которым нужно добавить ключ.
Виктор Зурковский
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.