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)

根据上图所示,采用utf8编码的字段最大长度为255个字符时,255*3+1=756,是小于最大767限制的,可以创建成功,如下

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

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)

ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes.的更多相关文章

  1. mysql 1709: Index column size too large. The maximum column size is 767 bytes.

    1709: Index column size too large. The maximum column size is 767 bytes. 修改排序规则解决 utf8_general_ci

  2. Index column size too large. The maximum column size is 767 bytes.

    mysql建表时报Index column size too large. The maximum column size is 767 bytes.解决办法:在建表语句的后面加入:ENGINE=In ...

  3. Mysql [Err] 1118 - Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535.

    对于越来越多的数据,数据库的容量越来越大,压缩也就越来越常见了.在我的实际工作中进行过多次压缩工作,也遇到多次问题,在此和大家分享一下. 首先,我们先说说怎么使用innodb的压缩. 第一,mysql ...

  4. The maximum column size is 767 bytes (Mysql)

     ERROR app.wsutils 419 INCRON: Error: ('HY000', '[HY000] [MySQL][ODBC 5.2(w) Driver][mysqld-5.7.7-rc ...

  5. MySQL Cluster测试过程中的错误汇总--ERROR 1296 (HY000)等等

    参考资料: http://dev.mysql.com/doc/refman/5.1/en/mysql-cluster-privilege-distribution.html http://www.cl ...

  6. mysql 报Row size too large 65535 原因与解决方法

    报错信息:Row size too large. The maximum row size for the used table type, not counting BLOBs, is 65535 ...

  7. Mysql_大字段问题Row size too large.....not counting BLOBs, is 8126.

    [问题描述] 1.从myslq(5.7.19-0ubuntu0.16.04.1)中导出sql脚本,导入到mysql(5.5.27)中,报如下错误:Row size too large. The max ...

  8. mysql触发器应用和创建表错误代码: 1118 Row size too large. 解决

    1.针对数据库查询问题的方便,可以建立重要表的log备份记录表,在主表的添加,修改,删除添加触发器,修改触发器增加触发字段的点,限制条件. 数据库log表查问题比从线上多台服务器上下载日志文件相对方便 ...

  9. Mysql [Err] 1118 - Row size too large

    首先声明,对MySQL不懂,很多都不知道原因 设计了一个表,里面很多text字段,然后填进去的东西太多(用的是Python的MySQLdb),报错: _mysql_exceptions.Operati ...

随机推荐

  1. 直通BAT必考题系列:JVM的4种垃圾回收算法、垃圾回收机制与总结

    垃圾回收算法 1.标记清除 标记-清除算法将垃圾回收分为两个阶段:标记阶段和清除阶段. 在标记阶段首先通过根节点(GC Roots),标记所有从根节点开始的对象,未被标记的对象就是未被引用的垃圾对象. ...

  2. eval与exec的区别,以及变量的作用范围

    # eval与exec的区别:eval 有返回值,而 exec没有返回值 # 这两个函数都是执行python语句,注意:里面传的是字符串的格式 a = eval('1+2') a # 这里a有值 3 ...

  3. List集合的方法总结

    1. 添加方法 boolean add(E e): 向集合的末尾添加指定的元素 boolean addAll(Collection<? extends E> c): 向集合的末尾添加一个指 ...

  4. Nowcoder 练习赛26 D xor序列 ( 线性基 )

    题目链接 题意 : 中文题.点链接 分析 : 对于给定的 X 和 Y 假设存在一个 Z 使得 X (xor) Z = Y 做一个变形 X (xor) Z (xor) Y = 0 X (xor) Y = ...

  5. AngularJS 前端 MVC 的设计与搭建

    代码 #未引入MVC框架之前的代码 <!doctype html> <html> <head> <meta charset="UTF-8" ...

  6. 【杂题】[CodeForces 1172F] Nauuo and Bug【数据结构】【线段树】

    Description 给出一个长度为n的序列a和一个整数p 有m组询问,每组询问给出一个区间\([l,r]\) 你需要给出下面这个过程的结果 ans = 0 for i from l to r { ...

  7. 详解vue的diff算法原理

    我的目标是写一个非常详细的关于diff的干货,所以本文有点长.也会用到大量的图片以及代码举例,目的让看这篇文章的朋友一定弄明白diff的边边角角. 先来了解几个点... 1. 当数据发生变化时,vue ...

  8. Oracle提高SQL查询效率where语句条件的先后次序

    (1)选择最有效率的表名顺序(只在基于规则的优化器中有效): Oracle的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 driving table)将被最先处 ...

  9. JS给XMLHttpRequest添加filter

    function XMLHttpRequestFilter(){ let base = XMLHttpRequest.prototype.open; let filter_list = []; let ...

  10. 191107Django的Cookie和Session

    Cookie的使用 from django.shortcuts import render,redirect def login(request): print("1",reque ...