mysql-Index column size too large. The maximum column size is 767 bytes.

MySQL版本和报错信息

MySQL版本5.6.35

在一个长度为512字符的字段上创建unique key报错

CREATE DATABASE dpcs_metadata DEFAULT CHARACTER SET utf8;
select * from information_schema.SCHEMATA;
+--------------+--------------------+----------------------------+------------------------+----------+
| CATALOG_NAME | SCHEMA_NAME        | DEFAULT_CHARACTER_SET_NAME | DEFAULT_COLLATION_NAME | SQL_PATH |
+--------------+--------------------+----------------------------+------------------------+----------+
| def          | information_schema | utf8                       | utf8_general_ci        | NULL     |
| def          | dpcs_metadata      | utf8                       | utf8_general_ci        | NULL     |
| def          | mysql              | utf8                       | utf8_bin               | NULL     |
| def          | performance_schema | utf8                       | utf8_general_ci        | NULL     |
| def          | test               | utf8                       | utf8_bin               | NULL     |
+--------------+--------------------+----------------------------+------------------------+----------+
5 rows in set (0.00 sec)

use dpcs_metadata;

create table raw_log_meta_data(
       id bigint NOT NULL AUTO_INCREMENT,
       app_id varchar(64),
       user_id varchar(128),
       file_path varchar(512),
       device_id varchar(128),
       update_time DATETIME,
       PRIMARY KEY (id),
       UNIQUE KEY (user_id),
       UNIQUE KEY (file_path)
       ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes

原因

MySQL用1到2个额外字节记录该字段的长度,当字段长度小于等于255时使用1个字节记录字段长度,当长度大于255时使用2~4个字节记录字段长度,字段file_path的长度为512*3+2=1538个字节,超过系统默认767字节数限制

		select * from information_schema.character_sets where character_set_name in('latin1', 'utf8', 'utf8mb4');
		+--------------------+----------------------+----------------------+--------+
		| CHARACTER_SET_NAME | DEFAULT_COLLATE_NAME | DESCRIPTION          | MAXLEN |
		+--------------------+----------------------+----------------------+--------+
		| latin1             | latin1_swedish_ci    | cp1252 West European |      1 |
		| utf8               | utf8_general_ci      | UTF-8 Unicode        |      3 |
		| utf8mb4            | utf8mb4_general_ci   | UTF-8 Unicode        |      4 |
		+--------------------+----------------------+----------------------+--------+
		3 rows in set (0.00 sec)
	
	
	create table raw_log_meta_data(
	       id bigint NOT NULL AUTO_INCREMENT,
	       app_id varchar(64),
	       user_id varchar(128),
	       file_path varchar(256),
	       device_id varchar(128),
	       update_time DATETIME,
	       PRIMARY KEY (id),
	       UNIQUE KEY (user_id),
	       UNIQUE KEY (file_path)
	       ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
	ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
	
	create table raw_log_meta_data(
	       id bigint NOT NULL AUTO_INCREMENT,
	       app_id varchar(64),
	       user_id varchar(128),
	       file_path varchar(255),
	       device_id varchar(128),
	       update_time DATETIME,
	       PRIMARY KEY (id),
	       UNIQUE KEY (user_id),
	       UNIQUE KEY (file_path)
	       ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
	Query OK, 0 rows affected (0.19 sec)
	
	desc raw_log_meta_data;
	+-------------+--------------+------+-----+---------+----------------+
	| Field       | Type         | Null | Key | Default | Extra          |
	+-------------+--------------+------+-----+---------+----------------+
	| id          | bigint(20)   | NO   | PRI | NULL    | auto_increment |
	| app_id      | varchar(64)  | YES  |     | NULL    |                |
	| user_id     | varchar(128) | YES  | UNI | NULL    |                |
	| file_path   | varchar(255) | YES  | UNI | NULL    |                |
	| device_id   | varchar(128) | YES  |     | NULL    |                |
	| update_time | datetime     | YES  |     | NULL    |                |
	+-------------+--------------+------+-----+---------+----------------+
	6 rows in set (0.01 sec)

解决方式

根据文档所述

https://dev.mysql.com/doc/refman/5.6/en/create-index.html

Prefix support and lengths of prefixes (where supported) are storage engine dependent. For example, a prefix can be up to 767 bytes long for InnoDB tables or 3072 bytes if the innodb_large_prefix option is enabled. For MyISAM tables, the prefix length limit is 1000 bytes. 

https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_large_prefix

innodb_large_prefix

Property	Value
Command-Line Format	--innodb-large-prefix[={OFF|ON}]
Introduced	5.6.3
System Variable	innodb_large_prefix
Scope	Global
Dynamic	Yes
Type	Boolean
Default Value	OFF
 

Enable this option to allow index key prefixes longer than 767 bytes (up to 3072 bytes) for InnoDB tables that use DYNAMIC or COMPRESSED row format. (Creating such tables also requires the option values innodb_file_format=barracuda and innodb_file_per_table=true.) See Section 14.6.1.6, “Limits on InnoDB Tables” for maximums associated with index key prefixes under various settings.

For tables that use REDUNDANT or COMPACT row format, this option does not affect the permitted index key prefix length.

 https://dev.mysql.com/doc/refman/5.6/en/innodb-restrictions.html

By default, the index key prefix length limit is 767 bytes. See Section 13.1.13, “CREATE INDEX Syntax”. For example, you might hit this limit with a column prefix index of more than 255 characters on a TEXT or VARCHAR column, assuming a utf8mb3 character set and the maximum of 3 bytes for each character. When theinnodb_large_prefix configuration option is enabled, the index key prefix length limit is raised to 3072 bytes for InnoDB tables that use DYNAMIC or COMPRESSED row format.

解决步骤

根据以上可知,如果需要在长度大于255字符的字段上创建索引,需要修改以下3个参数

1. 修改参数innodb_file_format=barracuda

2. 修改参数innodb_file_per_table=true

3. 修改参数ROW_FORMAT=DYNAMIC or COMPRESSED

具体SQL如下:

	mysql> show variables like 'innodb_large_prefix';
	+---------------------+-------+
	| Variable_name       | Value |
	+---------------------+-------+
	| innodb_large_prefix | OFF   |
	+---------------------+-------+
	1 row in set (0.00 sec)
	
	mysql> show variables like 'innodb_file_format';
	+--------------------+----------+
	| Variable_name      | Value    |
	+--------------------+----------+
	| innodb_file_format | Antelope |
	+--------------------+----------+
	1 row in set (0.00 sec)
	
	mysql> show variables like 'innodb_file_per_table';
	+-----------------------+-------+
	| Variable_name         | Value |
	+-----------------------+-------+
	| innodb_file_per_table | ON    |
	+-----------------------+-------+
	1 row in set (0.00 sec)
	
	mysql> set global innodb_large_prefix='on';
	Query OK, 0 rows affected (0.00 sec)
	
	mysql> set global innodb_file_format='Barracuda';
	Query OK, 0 rows affected (0.00 sec)
	
	mysql> show variables like 'innodb_large_prefix';
	+---------------------+-------+
	| Variable_name       | Value |
	+---------------------+-------+
	| innodb_large_prefix | ON    |
	+---------------------+-------+
	1 row in set (0.00 sec)
	
	mysql> show variables like 'innodb_file_format';
	+--------------------+-----------+
	| Variable_name      | Value     |
	+--------------------+-----------+
	| innodb_file_format | Barracuda |
	+--------------------+-----------+
	1 row in set (0.00 sec)

create table raw_log_meta_data(
       id bigint NOT NULL AUTO_INCREMENT,
       app_id varchar(64),
       user_id varchar(128),
       file_path varchar(512),
       device_id varchar(128),
       update_time DATETIME,
       PRIMARY KEY (id),
       UNIQUE KEY (user_id),
       UNIQUE KEY (file_path)
       ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
Query OK, 0 rows affected (0.29 sec)

转载

https://www.cnblogs.com/ilifeilong/p/11435675.html

=来自一泽涟漪的博客,转载请标明出处 www.cnblogs.com/ilifeilong=

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Index column size too large. The maximum column size is 767 bytes. 这个错误通常在MySQL数据库上建立索引时出现。具体原因是因为MySQL Innodb引擎表索引字段长度的限制是767字节。所以当对于多字节字符集的大字段(或者多字段组合索引)创建索引时,会出现这个错误。 解决这个问题的方法有几种。一种方法是减少索引字段的长度,比如将字段长度缩短到767字节以下。另一种方法是使用前缀索引,通过只索引字段的前几个字符来解决。还有一种方法是更改数据库的字符集,将字符集改为utf8或者latin等较小的字符集。 如果你使用的是MySQL 5.7.7或更高版本,还可以通过修改配置文件来解决这个问题。在配置文件中添加以下内容: ``` <span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [提要:自托管的RSS阅读器-带有Symfony的API-独立的html客户端-Google阅读器替代](https://download.csdn.net/download/weixin_42127748/15095482)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [解决MySQL报 index column size too large. the maximum column size is 767 bytes 问题](https://blog.csdn.net/weixin_52005792/article/details/118157681)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Index column size too large. The maximum column size is 767 bytes.](https://blog.csdn.net/m0_71124383/article/details/129809980)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值