mysql - without - столбец типа blob был указан в определении ключа без указания длины ключа




Ошибка MySQL: спецификация ключа без ключа (9)

У меня есть таблица с первичным ключом, который является varchar (255). Некоторые случаи возникли, когда 255 символов недостаточно. Я попытался изменить поле на текст, но я получаю следующую ошибку:

BLOB/TEXT column 'message_id' used in key specification without a key length

Как я могу это исправить?

edit: Я должен также указать, что эта таблица имеет составной первичный ключ с несколькими столбцами.


MySQL запрещает индексирование полного значения BLOB , TEXT и длинных столбцов VARCHAR поскольку данные, которые они содержат, могут быть огромными, и неявно индекс DB будет большим, что не означает выгоды от индекса.

MySQL требует, чтобы вы определили первые N символов для индексирования, и трюк состоит в том, чтобы выбрать число N, которое достаточно длинное, чтобы обеспечить хорошую избирательность, но достаточно короткое, чтобы сэкономить место. Префикс должен быть достаточно длинным, чтобы сделать индекс почти таким же полезным, как если бы вы проиндексировали весь столбец.

Прежде чем идти дальше, давайте определим некоторые важные термины. Селективность индекса - это отношение всех отдельных индексированных значений и общего количества строк . Вот один пример тестовой таблицы:

+-----+-----------+
| id  | value     |
+-----+-----------+
| 1   | abc       |
| 2   | abd       |
| 3   | adg       |
+-----+-----------+

Если мы индексируем только первый символ (N = 1), тогда таблица индексов будет выглядеть как следующая таблица:

+---------------+-----------+
| indexedValue  | rows      |
+---------------+-----------+
| a             | 1,2,3     |
+---------------+-----------+

В этом случае селективность индекса равна IS = 1/3 = 0,33.

Давайте посмотрим, что произойдет, если мы увеличим число индексированных символов до двух (N = 2).

+---------------+-----------+
| indexedValue  | rows      |
+---------------+-----------+
| ab             | 1,2      |
| ad             | 3        |
+---------------+-----------+

В этом сценарии IS = 2/3 = 0,66, что означает увеличение селективности индекса, но мы также увеличили размер индекса. Трюк состоит в том, чтобы найти минимальное число N, которое приведет к максимальной селективности индекса .

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

Предположим, мы хотим добавить столбец last_name в таблице сотрудников в индекс, и мы хотим определить наименьшее число N, которое будет обеспечивать лучшую селективность индекса.

Сначала давайте определим наиболее часто используемые фамилии:

select count(*) as cnt, last_name 
from employees 
group by employees.last_name 
order by cnt

+-----+-------------+
| cnt | last_name   |
+-----+-------------+
| 226 | Baba        |
| 223 | Coorg       |
| 223 | Gelosh      |
| 222 | Farris      |
| 222 | Sudbeck     |
| 221 | Adachi      |
| 220 | Osgood      |
| 218 | Neiman      |
| 218 | Mandell     |
| 218 | Masada      |
| 217 | Boudaillier |
| 217 | Wendorf     |
| 216 | Pettis      |
| 216 | Solares     |
| 216 | Mahnke      |
+-----+-------------+
15 rows in set (0.64 sec)

Как вы можете видеть, последнее имя Баба является самым частым. Теперь мы собираемся найти наиболее часто встречающиеся префиксы last_name , начиная с пятибуквенных префиксов.

+-----+--------+
| cnt | prefix |
+-----+--------+
| 794 | Schaa  |
| 758 | Mande  |
| 711 | Schwa  |
| 562 | Angel  |
| 561 | Gecse  |
| 555 | Delgr  |
| 550 | Berna  |
| 547 | Peter  |
| 543 | Cappe  |
| 539 | Stran  |
| 534 | Canna  |
| 485 | Georg  |
| 417 | Neima  |
| 398 | Petti  |
| 398 | Duclo  |
+-----+--------+
15 rows in set (0.55 sec)

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

Вот результаты для N = 9

select count(*) as cnt, left(last_name,9) as prefix 
from employees 
group by prefix 
order by cnt desc 
limit 0,15;

+-----+-----------+
| cnt | prefix    |
+-----+-----------+
| 336 | Schwartzb |
| 226 | Baba      |
| 223 | Coorg     |
| 223 | Gelosh    |
| 222 | Sudbeck   |
| 222 | Farris    |
| 221 | Adachi    |
| 220 | Osgood    |
| 218 | Mandell   |
| 218 | Neiman    |
| 218 | Masada    |
| 217 | Wendorf   |
| 217 | Boudailli |
| 216 | Cummings  |
| 216 | Pettis    |
+-----+-----------+

Вот результаты для N = 10.

+-----+------------+
| cnt | prefix     |
+-----+------------+
| 226 | Baba       |
| 223 | Coorg      |
| 223 | Gelosh     |
| 222 | Sudbeck    |
| 222 | Farris     |
| 221 | Adachi     |
| 220 | Osgood     |
| 218 | Mandell    |
| 218 | Neiman     |
| 218 | Masada     |
| 217 | Wendorf    |
| 217 | Boudaillie |
| 216 | Cummings   |
| 216 | Pettis     |
| 216 | Solares    |
+-----+------------+
15 rows in set (0.56 sec)

Это очень хорошие результаты. Это означает, что мы можем сделать индекс по столбцу last_name с индексированием только первых 10 символов. В столбце определения таблицы last_name определяется как VARCHAR(16) , и это означает, что мы сохранили 6 байтов (или больше, если есть символы UTF8 от имени) для каждой записи. В этой таблице 1637 различных значений, умноженных на 6 байтов, составляют около 9 КБ, и представьте, как это число будет расти, если наша таблица содержит миллион строк.

Вы можете читать другие способы вычисления числа N в моем сообщении. Предварительно префиксы индексов в MySQL .


Вы должны изменить тип столбца на varchar или integer для индексирования.


Вы можете указать длину ключа в запросе alter table, например:

alter table authors ADD UNIQUE(name_first(20), name_second(20));

Добавьте еще один столбец varChar (255) (по умолчанию как пустая строка, не равная null), чтобы удерживать переполнение, когда 255 символов недостаточно, и измените этот PK на использование обоих столбцов. Однако это не похоже на хорошо разработанную схему базы данных, и я бы рекомендовал получить модель данных данных, чтобы посмотреть, что у вас есть, с целью рефакторинга для большей нормализации.


Используйте это

@Id
@Column(name = "userEmailId", length=100)
private String userEmailId;

Кроме того, если вы хотите использовать индекс в этом поле, вы должны использовать механизм хранения MyISAM и индексный тип FULLTEXT.


Перейдите в edit table mysql -> измените тип столбца на varchar(45) .


Решение проблемы заключается в том, что в вашем операторе CREATE TABLE вы можете добавить ограничение UNIQUE ( problemtextfield(300) ) после того, как столбец создаст определения, чтобы указать длину key 300 символов для поля TEXT , например. Тогда первые 300 символов поля problemtextfield TEXT должны быть уникальными, и любые различия после этого будут проигнорированы.


alter table authors ADD UNIQUE(name_first(767), name_second(767));

ПРИМЕЧАНИЕ . 767 - это количество символов, до которых MySQL будет индексировать столбцы при работе с индексами blob / text

Ссылка: http://dev.mysql.com/doc/refman/5.7/en/innodb-restrictions.html







mysql-error-1170