У нас есть несколько инженеров, которые объединяют нормализованную структуру БД во временную таблицу для создания отчета. Столбцы указаны как TEXT NOT NULL
(я знаю, «почему они это делают?»; Давайте просто предположим, что мы обращаемся к этому).
Мы используем MySQL 5.1.48 Community RHEL5 с плагином InnoDB 1.0.9 в Linux.
При использовании MyISAM мы никогда не сталкивались с предельными размерами таблицы максимальными столбцами или максимальной длиной строки (во время исследования мы достигли максимального значения столбцов 2598 (2599th вызывает ошибку 1117). С InnoDB мы достигаем пределов. Эти ограничения проявляются при создании таблица (без вставки данных) как:
ОШИБКА 1118 (42000) в строке 1: слишком большой размер строки. Максимальный размер строки для используемого типа таблицы, не считая больших двоичных объектов, составляет 8126. Некоторые столбцы необходимо изменить на TEXT или BLOB.
Я ищу ответы на следующие вопросы:
Какова детальная формула для определения размера строки при использовании партий столбцов v / v / b / t? Я пробовал несколько различных формул, используя
varchar(N)
столбцы (где N находится между 1 и 512), кодировку UTF8 (* 3) и столько столбцов, сколько таблица займет до сбоя. Ни одна из комбинаций, которые я пробовал, не дает значений, которые соответствуют реальным результатам теста.Какие еще «накладные расходы» следует учитывать при расчете размера строки?
Почему сообщение об ошибке меняется с 8126 на 65535 при переходе от создания таблиц со столбцами varchar (109) к столбцам varchar (110)?
Ответы:
Ответы на ваши вопросы являются сложными, потому что они различаются в зависимости от формата файла InnoDB . На сегодняшний день существует два формата, называемые Антилопа и Барракуда.
Центральный файл табличного пространства (ibdata1) всегда имеет формат антилопы . Если вы используете файл для каждой таблицы, вы можете настроить отдельные файлы в формате Barracuda , установив
innodb_file_format=Barracuda
в my.cnf.Основные моменты:
Одна страница размером 16 КБ данных InnoDB должна содержать как минимум две строки данных. Кроме того, каждая страница имеет верхний и нижний колонтитулы, содержащие контрольные суммы страниц и порядковый номер журнала и так далее. Вот где вы получите свой предел чуть менее 8 КБ на строку.
Типы данных фиксированного размера, такие как INTEGER, DATE, FLOAT, CHAR, хранятся на этой первичной странице данных и учитываются при ограничении размера строки.
Типы данных переменного размера, такие как VARCHAR, TEXT, BLOB, хранятся на страницах переполнения, поэтому они не учитываются полностью до предела размера строки. В антилопе до 768 байт таких столбцов хранятся на первичной странице данных в дополнение к хранению на странице переполнения. Barracuda поддерживает динамический формат строки , поэтому он может хранить только 20-байтовый указатель на первичной странице данных.
Типы данных переменного размера также имеют префикс 1 или более байтов для кодирования длины. И формат строки InnoDB также имеет массив смещений полей. Так что в их вики есть более или менее задокументированная внутренняя структура . [ПРАВКА] Мертвая ссылка - здесь выглядит лучше.
Barracuda также поддерживает ROW_FORMAT = COMPRESSED для повышения эффективности хранения данных переполнения.
Я также должен отметить, что я никогда не видел, чтобы хорошо спроектированная таблица превышала предел размера строки. Это сильный "кодовый запах", что вы нарушаете условие повторяющихся групп в первой нормальной форме.
источник
Моя ситуация немного отличается. Один из элементов данных, который мне нужно хранить в каждой строке, потенциально очень большой. (Поле данных является LONGBLOB для документа, который может содержать несколько встроенных изображений. Моя примерная база данных содержит документы размером до 25–30 МБ, но в некоторых случаях эти документы могут быть больше.) Ни одно из решений, которые я нашел в Интернете, не помогло , (Изменен тип файла InnoDB на Barracuda, увеличен размер файла журнала, установлен формат строки в COMPRESSED.)
Единственное найденное мной решение, которое сработало, - вернуться к MySQL 5.5.x из MySQL 5.6.x.
источник