У меня есть таблица с первичным ключом, который является varchar (255). Возникло несколько случаев, когда 255 символов недостаточно. Я попытался изменить поле на текст, но я получаю следующую ошибку:
BLOB/TEXT column 'message_id' used in key specification without a key length
Как я могу это исправить?
редактировать: я также должен отметить, что эта таблица имеет составной первичный ключ с несколькими столбцами.
mysql
sql
mysql-error-1170
GSto
источник
источник
UNIQUE
ключей?Ответы:
Ошибка происходит, потому что MySQL может индексировать только первые N символов BLOB или
TEXT
столбца. Таким образом , ошибка в основном происходит , когда есть поле типа / столбецTEXT
или BLOB или те , принадлежатTEXT
илиBLOB
типов , таких какTINYBLOB
,MEDIUMBLOB
,LONGBLOB
,TINYTEXT
,MEDIUMTEXT
, иLONGTEXT
что вы пытаетесь сделать первичный ключ или индекс. С полнымBLOB
илиTEXT
без значения длины MySQL не может гарантировать уникальность столбца, так как он имеет переменный и динамический размер. Таким образом, при использованииBLOB
илиTEXT
в качестве индекса необходимо указывать значение N, чтобы MySQL мог определить длину ключа. Однако MySQL не поддерживает ограничение длины ключа дляTEXT
илиBLOB
.TEXT(88)
просто не сработает.Ошибка также появится, когда вы попытаетесь преобразовать столбец таблицы из
non-TEXT
иnon-BLOB
введите, например,VARCHAR
иENUM
вTEXT
илиBLOB
введите, причем столбец уже определен как уникальные ограничения или индекс. Команда Alter Table SQL не будет выполнена.Решение проблемы - удалить столбец
TEXT
илиBLOB
из индекса или ограничения уникальности или задать другое поле в качестве первичного ключа. Если вы не можете этого сделать и хотите установить ограничение на столбецTEXT
илиBLOB
, попробуйте использоватьVARCHAR
тип и наложить ограничение длины. По умолчаниюVARCHAR
он ограничен максимум 255 символами, и его предел должен быть указан неявно в скобках сразу после его объявления, то естьVARCHAR(200)
будет ограничен только длиной до 200 символов.Иногда, даже если вы не используете
TEXT
илиBLOB
связанный тип в вашей таблице, ошибка 1170 также может появляться. Это происходит в ситуации, когда вы указываетеVARCHAR
столбец в качестве первичного ключа, но неправильно устанавливаете его длину или размер символов.VARCHAR
может принимать только до 256 символов, поэтому что-либо, напримерVARCHAR(512)
, заставит MySQL автоматически преобразовать тип данныхVARCHAR(512)
вSMALLTEXT
тип данных, что впоследствии приводит к ошибке 1170 по длине ключа, если столбец используется в качестве первичного ключа или уникального или неуникального индекса. Чтобы решить эту проблему, укажите в качестве размераVARCHAR
поля значение менее 256 .Ссылка: MySQL Error 1170 (42000): столбец BLOB / TEXT, используемый в спецификации ключа без длины ключа
источник
Вы должны определить, какую ведущую часть
TEXT
столбца вы хотите проиндексировать.InnoDB
имеет ограничение в768
байтах на ключ индекса, и вы не сможете создать индекс дольше.Это будет хорошо работать:
Обратите внимание, что максимальное значение размера ключа зависит от набора символов столбца. Это
767
символы для однобайтовой кодировки, такие какLATIN1
и только255
символыUTF8
(MySQL
только для использования,BMP
которое требует не более3
байтов на символ)Если вам нужен весь столбец для
PRIMARY KEY
вычисления, вычисленияSHA1
илиMD5
хэширования и используйте его какPRIMARY KEY
.источник
REDUNDANT
илиCOMPACT
. Например, вы можете установить этот предел с индексом префикса столбца более 255 символов для столбцаTEXT
илиVARCHAR
, предполагая набор символов utf8mb3 и максимум 3 байта для каждого символа.REDUNDANT
иCOMPACT
были единственными форматами, доступными в то время, когда был дан этот ответ.Вы можете указать длину ключа в запросе alter table, например:
источник
MySQL Запрещает индексации полной стоимости
BLOB
,TEXT
и длинныеVARCHAR
столбцы , так как данные , которые они содержат , может быть огромными, и неявно индекс DB будут большими, не означают никакой пользы от индекса.MySQL требует, чтобы вы указали первые N символов для индексации, и хитрость заключается в том, чтобы выбрать число N, которое достаточно длинное, чтобы обеспечить хорошую селективность, но достаточно короткое, чтобы сэкономить место. Префикс должен быть достаточно длинным, чтобы индекс был почти таким же полезным, как если бы вы проиндексировали весь столбец.
Прежде чем идти дальше, давайте определимся с некоторыми важными терминами. Селективность индекса - это отношение общего числа индексируемых значений к общему числу строк . Вот один пример для тестовой таблицы:
Если мы будем индексировать только первый символ (N = 1), тогда таблица индекса будет выглядеть следующим образом:
В этом случае индекс селективности равен IS = 1/3 = 0,33.
Давайте теперь посмотрим, что произойдет, если мы увеличим количество проиндексированных символов до двух (N = 2).
В этом сценарии IS = 2/3 = 0,66, что означает, что мы увеличили селективность индекса, но мы также увеличили размер индекса. Хитрость заключается в том, чтобы найти минимальное число N, которое приведет к максимальной селективности индекса .
Есть два подхода, которые вы можете сделать вычисления для вашей таблицы базы данных. Я сделаю демонстрацию на этом дампе базы данных .
Допустим, мы хотим добавить столбец last_name из таблицы employee в индекс, и мы хотим определить наименьшее число N, которое обеспечит наилучшую селективность индекса.
Сначала давайте определим наиболее частые фамилии:
Как видите, фамилия Баба - самая частая. Теперь мы собираемся найти наиболее часто встречающиеся префиксы last_name , начиная с пятибуквенных префиксов.
Каждый префикс встречается гораздо чаще, что означает, что мы должны увеличивать число N, пока значения не станут почти такими же, как в предыдущем примере.
Вот результаты для N = 9
Вот результаты для N = 10.
Это очень хорошие результаты. Это означает, что мы можем сделать индекс по столбцу
last_name
с индексированием только первых 10 символов. В таблице определение столбцаlast_name
определяется какVARCHAR(16)
, и это означает, что мы сохранили 6 байтов (или больше, если в фамилии есть символы UTF8) для каждой записи. В этой таблице 1637 различных значений, умноженных на 6 байтов, составляют около 9 КБ, и представьте, как это число будет расти, если наша таблица будет содержать миллион строк.Вы можете прочитать другие способы вычисления числа N в моем посте Префиксные индексы в MySQL .
источник
Я получил эту ошибку при добавлении индекса в таблицу со столбцами текстового типа. Вам необходимо указать размер, который вы хотите использовать для каждого типа текста.
Укажите размер в скобках ()
Если используется слишком много байтов, вы можете объявить размер в скобках для varchar, чтобы уменьшить объем, используемый для индексации. Это даже если вы объявили размер для типа, уже похожего на varchar (1000). Вам не нужно создавать новую таблицу, как говорили другие.
Добавление индекса
Добавление уникального индекса
источник
ПРИМЕЧАНИЕ : 767 - это количество символов, до которого MySQL будет индексировать столбцы при работе с BLOB / текстовыми индексами.
Ссылка: http://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html
источник
Другой отличный способ справиться с этим - создать поле TEXT без уникального ограничения и добавить одноуровневое поле VARCHAR, которое является уникальным и содержит дайджест (MD5, SHA1 и т. Д.) Поля TEXT. Рассчитайте и сохраните дайджест по всему полю TEXT, когда вы вставите или обновите поле TEXT, тогда у вас будет ограничение уникальности по всему полю TEXT (а не по какой-либо ведущей части), которое можно быстро найти.
источник
Не используйте длинные значения в качестве первичного ключа. Это разрушит вашу производительность. См. Руководство по mysql, раздел 13.6.13 «Настройка производительности InnoDB и устранение неполадок».
Вместо этого используйте суррогатный ключ int как первичный (с auto_increment), а ключ loong - как вторичный UNIQUE.
источник
Добавьте еще один столбец varChar (255) (по умолчанию в качестве пустой строки не ноль), чтобы удерживать переполнение, когда недостаточно 255 символов, и измените этот PK, чтобы использовать оба столбца. Однако это не похоже на хорошо спроектированную схему базы данных, и я бы порекомендовал получить средство моделирования данных, чтобы взглянуть на то, что у вас есть, с целью его рефакторинга для большей нормализации.
источник
Решение проблемы заключается в
CREATE TABLE
том, что в своем утверждении вы можете добавить ограничениеUNIQUE ( problemtextfield(300) )
после того, как столбец создаст определения, например, для указанияkey
длины300
символов дляTEXT
поля. Тогда первые300
символыproblemtextfield
TEXT
поля должны быть уникальными, и любые различия после этого будут игнорироваться.источник
Кроме того, если вы хотите использовать индекс в этом поле, вы должны использовать механизм хранения MyISAM и тип индекса FULLTEXT.
источник
Пока никто не упомянул об этом ... с utf8mb4, который является 4-байтовым и может также хранить смайлики (мы никогда не должны больше использовать 3-байтовый utf8), и мы можем избежать ошибок, таких как
Incorrect string value: \xF0\x9F\x98\...
мы должны использовать не типичный VARCHAR (255), а VARCHAR ( 191) потому что в случае utf8mb4 и VARCHAR (255) одна и та же часть данных сохраняется вне страницы, и вы не можете создать индекс для столбца VARCHAR (255), но для VARCHAR (191) вы можете это сделать. Это связано с тем, что максимальный размер индексированного столбца составляет 767 байт для ROW_FORMAT = COMPACT или ROW_FORMAT = REDUNDANT.Для более новых форматов строк ROW_FORMAT = DYNAMIC или ROW_FORMAT = COMPRESSED (для которого требуется более новый формат файла innodb_file_format = Barracuda not old Antelope) максимальный размер индексированного столбца составляет 3072. Он доступен с MySQL> = 5.6.3, когда innodb_large_prefix = 1 (по умолчанию отключено для MySQL <= 5.7.6 и включен по умолчанию для MySQL> = 5.7.7). Таким образом, в этом случае мы можем использовать VARCHAR (768) для utf8mb4 (или VARCHAR (1024) для старого utf8) для индексированного столбца. Опция innodb_large_prefix устарела с 5.7.7, потому что ее поведение встроено в MySQL 8 (в этой версии опция удалена).
источник
Вы должны изменить тип столбца на
varchar
илиinteger
для индексации.источник
Перейти к MySQL
edit table
-> изменить тип столбца наvarchar(45)
.источник
Используйте как это
источник