MySQL错误:没有密钥长度的密钥规范

MySQL错误:没有密钥长度的密钥规范,mysql,sql,mysql-error-1170,Mysql,Sql,Mysql Error 1170,我有一个主键为varchar(255)的表。有些情况下,255个字符不够。我尝试将字段更改为文本,但出现以下错误: BLOB/TEXT column 'message_id' used in key specification without a key length 我怎样才能解决这个问题 编辑:我还应该指出,这个表有一个包含多个列的复合主键。发生错误是因为MySQL只能索引BLOB或TEXT列的前N个字符。因此,错误主要发生在存在TEXT或BLOB的字段/列类型,或属于TEXT或BLOB类

我有一个主键为varchar(255)的表。有些情况下,255个字符不够。我尝试将字段更改为文本,但出现以下错误:

BLOB/TEXT column 'message_id' used in key specification without a key length
我怎样才能解决这个问题


编辑:我还应该指出,这个表有一个包含多个列的复合主键。

发生错误是因为MySQL只能索引BLOB或
TEXT
列的前N个字符。因此,错误主要发生在存在
TEXT
或BLOB的字段/列类型,或属于
TEXT
BLOB
类型的字段/列类型时,例如
TINYBLOB
MEDIUMBLOB
LONGBLOB
TINYTEXT
MEDIUMTEXT
,和
LONGTEXT
,您尝试创建主键或索引。如果full
BLOB
TEXT
没有长度值,MySQL无法保证列的唯一性,因为它的大小是可变的和动态的。因此,当使用
BLOB
TEXT
类型作为索引时,必须提供N值,以便MySQL可以确定密钥长度。但是,MySQL不支持对
TEXT
BLOB
的键长度限制<代码>文本(88)根本不起作用

当您尝试将表列从
非文本
非BLOB
类型(如
VARCHAR
ENUM
转换为
文本
BLOB
类型)时,也会弹出错误,并且列已定义为唯一约束或索引。ALTERTABLESQL命令将失败


该问题的解决方案是从索引或唯一约束中删除
TEXT
BLOB
列,或将另一个字段设置为主键。如果您无法做到这一点,并且希望对
TEXT
BLOB
列设置限制,请尝试使用
VARCHAR
键入并对其设置长度限制。默认情况下,
VARCHAR
的最大长度限制为255个字符,其限制必须在声明后的括号内隐式指定,即
VARCHAR(200)
将其长度限制为200个字符

有时,即使您没有在表中使用
TEXT
BLOB
相关类型,也可能会出现错误1170。它发生在这样一种情况下:指定
VARCHAR
列作为主键,但错误地设置了其长度或字符大小
VARCHAR
最多只能接受256个字符,因此任何诸如
VARCHAR(512)
之类的操作都会强制MySQL将
VARCHAR(512)
自动转换为
SMALLTEXT
数据类型,如果该列用作主键或唯一或非唯一索引,则随后将失败,键长度出现错误1170。要解决此问题,请指定小于256的数字作为
VARCHAR
字段的大小


参考资料:

您应该定义要索引的
文本
列的前导部分

InnoDB
对每个索引键的限制为
768
字节,您将无法创建比这更长的索引

这很好:

CREATE TABLE t_length (
      mydata TEXT NOT NULL,
      KEY ix_length_mydata (mydata(255)))
    ENGINE=InnoDB;
请注意,键大小的最大值取决于列字符集。对于单字节字符集,如
LATIN1
,它是
767个
字符,对于
UTF8
,它只有
255个
字符(
MySQL
仅使用
BMP
,每个字符最多需要
3个
字节)


如果需要将整个列作为
主键
,请计算
SHA1
MD5
散列,并将其用作
主键

添加另一个varChar(255)列(默认为空字符串不为null),以在255个字符不足时保留溢出,并将此主键更改为同时使用这两个列。不过,这听起来不像是一个设计良好的数据库模式,我建议让数据建模师看看您有什么,以便对其进行重构以实现更多的规范化。

您可以在alter table请求中指定键长度,例如:

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

没有长值作为主键。那会毁了你的表现。请参阅mysql手册第13.6.13节“InnoDB性能调优和故障排除”


取而代之的是,将代理int键作为主键(具有自动增量),将long键作为次唯一键。

此外,如果要在此字段中使用索引,您应该使用MyISAM存储引擎和全文索引类型。

另一个很好的处理方法是创建没有唯一约束的文本字段,并添加唯一的同级VARCHAR字段,该字段包含文本字段的摘要(MD5、SHA1等)。在插入或更新文本字段时,计算并存储整个文本字段的摘要,然后可以快速搜索整个文本字段(而不是某些前导部分)的唯一性约束。

MySQL不允许为
BLOB
的完整值编制索引,
TEXT
和long
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

现在让我们看看如果我们增加索引ch的数量会发生什么
+---------------+-----------+
| indexedValue  | rows      |
+---------------+-----------+
| ab             | 1,2      |
| ad             | 3        |
+---------------+-----------+
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)
+-----+--------+
| 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)
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    |
+-----+-----------+
+-----+------------+
| 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)
alter table authors ADD UNIQUE(name_first(767), name_second(767));
@Id
@Column(name = "userEmailId", length=100)
private String userEmailId;
alter table test add index index_name(col1(255),col2(255));
alter table test add unique index_name(col1(255),col2(255));
ALTER TABLE table_name MODIFY COLUMN col_name datatype;
ALTER TABLE my_table MODIFY COLUMN my_col VARCHAR(255);