Код помилки 1117 Забагато стовпців; Ліміт стовпців MySQL на столі


37

У мене є таблиця з 1699 стовпцями, і коли я намагаюся вставити більше стовпців, я отримую,

Код помилки: 1117. Забагато стовпців

У цій таблиці я лише 1000 рядків. Для мене найголовніше - кількість стовпців. Чи є якісь обмеження на столі? Я хочу створити 2000 стовпців. Це можливо?


22
Добрий пане, що за чорт. Це пахне шалено поганим дизайном бази даних. Або, можливо, ви використовуєте неправильний інструмент для роботи. Можливо, вам слід поглянути на нормалізацію бази даних
Zoredache

12
Поверніть монітор на 90 градусів. Більш серйозно, MySQL (або майже будь-який інший RDBMS) не розроблений для ТАКОГО багатьох стовпців.

11
І чому 2000 датчиків повинні вести до 2000 колонок? Переробіть свою базу даних. Створіть окрему таблицю датчиків чи щось таке, але НЕ додайте кожен датчик як новий стовпець. Це просто неймовірно неправильно робити.

6
Максимальне число столу ... що там! Ймовірно, вам знадобиться лише кілька таблиць. Навіть не роздумуйте про створення 2000 таблиць замість 2000 стовпців!

2
Будь ласка, будь ласка, прочитайте про нормалізацію бази даних !

Відповіді:


35

Навіщо вам потрібно створити таблицю з навіть 20 стовпцями, не кажучи вже про 2000 ???

Надані, денормалізовані дані можуть запобігти необхідності JOIN для отримання багатьох стовпців даних. Однак якщо у вас більше 10 стовпців, вам слід зупинитися і подумати про те, що буде під кришкою під час пошуку даних.

Якщо таблиця стовпців 2000 зазнає SELECT * FROM ... WHERE, ви будете генерувати великі тимчасові таблиці під час обробки, вибирати непотрібні стовпці та створювати безліч сценаріїв, коли пакети зв'язку ( max_allowed_packet ) будуть висунуті на межі кожного запиту.

У попередні дні як розробник я працював у компанії ще в 1995 році, де DB2 був основною RDBMS. Компанія мала єдину таблицю, яка складала 270 стовпців, десятки індексів і мала проблеми з результатами пошуку даних. Вони зв’язалися з IBM і мали консультантів, які розглядають архітектуру своєї системи, включаючи цю єдину монолітну таблицю. Компанії сказали: "Якщо ви не нормалізуєте цю таблицю протягом наступних 2 років, DB2 не зможе виконати запити, що виконують Stage2 Processing (будь-які запити, що потребують сортування за неіндексованими стовпцями). Про це було сказано багатомільйонній компанії, щоб нормалізувати таблицю з 270 стовпчиків. Наскільки більше, так 2000 таблиця стовпців.

З точки зору mysql, вам доведеться компенсувати такий поганий дизайн, встановивши параметри, порівнянні з DB2 Stage2 Processing. У цьому випадку такі варіанти були б

Налаштування цих параметрів компенсує наявність десятків, не кажучи вже про сотні, стовпців, добре працює, якщо у вас є ТБ оперативної пам’яті.

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

ВИСНОВОК

Немає замінника чи пов'язки, яка може компенсувати поганий дизайн. Будь ласка, заради вашого розуму в майбутньому нормалізуйте цю таблицю сьогодні !!!


1
Я міг би уявити, як буде діяти компанія, коли про це розповіли. Вони додають гачки svn або створюють "рекомендації щодо найкращої практики БД" з проханням розробників не сортувати неіндексовані стовпці в SQL. Натомість вони здійснюють сортування у програмі, реалізуючи власний великий алгоритм сортування даних.
Gqqnbig

25

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

Я здогадуюсь, що ви, ймовірно, робите якусь денормалізовану схему "заповнення пробілів", де ви фактично зберігаєте всі різні види даних в одній таблиці, а замість того, щоб розбивати дані на окремі таблиці та встановлювати відносини , у вас є різні поля, які записують, який "тип" даних зберігається в заданому рядку, і 90% ваших полів - NULL. Навіть тоді, хотіти, щоб дістатися до 2000 колонок ... виходить.

Рішення вашої проблеми - переосмислити вашу модель даних. Якщо ви зберігаєте велику купу ключових / значущих даних, пов’язаних із заданим записом, чому б не моделювати це саме так? Щось на зразок:

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 датчиками

Ігноруйте всі коментарі, що кричать про нормалізацію - те, про що ви просите, може бути розумним дизайном баз даних (в ідеальному світі) і ідеально добре нормалізованим, це просто дуже незвично, і як зазначалося в інших місцях, RDBMS зазвичай просто не розроблені для цього багатьох стовпців .

Хоча ви не досягаєте жорсткого обмеження MySQL , один з інших факторів, згаданих у посиланні, ймовірно, заважає вам піднятися вище

Як говорять інші, ви можете подолати це обмеження, маючи дочірню таблицю id, sensor_id, sensor_value, або, простіше кажучи, ви можете створити другу таблицю, яка містить лише стовпці, які не вмістяться в першому (і використовувати той самий ПК)


1
Це правда. Коли ви дуже обережно обробляєте дані та відповідний SQL, ваша відповідь виділяється ще більше !!!
RolandoMySQLDBA

3
Використання дочірньої таблиці не є "вирішенням". Мати по одному стовпчику для кожного датчика - це просто погана (неправильна) конструкція. Це як би мати один стовпчик для кожного працівника в системі управління персоналом, або один стовпчик для кожного виробника автомобіля для БД, який керує моделями автомобілів.
a_horse_with_no_name

11
@a_horse - ви робите припущення, які, я сумніваюся, є дійсними. Цілком можливо, що кількість датчиків в основному фіксовано, що всі читаються одночасно і всі повертають дані кожен раз. У цьому випадку один стовпчик на датчик не є "неправильним", просто недоцільно, враховуючи обмеження бази даних. Мені подобається вважати, що запитуючі не є ідіотами, поки не доведеться інше, і iUngi гідно відповів перед дуже недобрими відповідями натовпу СФ.
Джек Дуглас

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.

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

Ви індексуєте якесь із значень? Вам потрібно пошукати їх? Можливо, ви шукаєте на дату?

Якщо вам потрібно проіндексувати багато стовпців - punt.

Якщо вам потрібно проіндексувати декілька - покладіть їх у головну таблицю.

Ось справжнє рішення (якщо воно застосовується) ...

Якщо вам не потрібен великий масив датчиків, індексований, то не робіть стовпчиків! Так, ви мене почули. Натомість збирайте їх у JSON, стискайте JSON, зберігайте у полі BLOB. Ви заощадите тонну місця; у вас буде лише одна таблиця, без проблем з обмеженням стовпців; т. т. Ваша програма не скасуватиме, а потім використовувати JSON як структуру. Вгадай що? Ви можете мати структуру - ви можете згрупувати датчики в масиви, багаторівневі речі тощо, так, як хотів би ваш додаток. Ще одна «особливість» - це відкритість. Якщо ви додасте більше датчиків, вам не потрібно ЗНАЧІТЬ таблицю. JSON, якщо таким чином гнучким.

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


Це справді найкраща відповідь. Добре коментувати, що, можливо, він повинен досліджувати, не маючи стільки стовпців, але якщо прийнята відповідь "не роби цього" не відповідає на запитання. Навіть якщо цей хлопець не дуже потребує стільки стовпців, можливо, хтось, хто знаходить це питання, потребує стільки, і потребує реальної відповіді.
BoB3K

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

3

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

Є час і місце для цього дизайну. Зовсім. Нормалізація - це не рішення кожної проблеми.


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