Laravel迁移添加联合唯一索引触发1071键过长错误,求排查
问题:Laravel迁移添加联合唯一索引时触发1071错误
操作场景与迁移代码
尝试为pending_tasks表添加包含actionable_id、actionable_type、step字段的联合唯一索引,索引名为unique_tasks,迁移代码如下:
Schema::table('pending_tasks', function (Blueprint $table) { $table->unique(['actionable_id', 'actionable_type', 'step'], 'unique_tasks'); });
执行时的错误信息
Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes
(SQL:alter table pending_tasks add unique 'unique_tasks'('actionable_id', 'actionable_type', step')).
补充配置与表结构信息
- 原本全局配置数据库引擎为
InnoDB ROW_FORMAT=DYNAMIC,且已在AppServiceProvider.php中添加Schema::defaultStringLength(191); - 实际
pending_tasks表使用的是MyISAM引擎,表创建语句如下:
CREATE TABLE `pending_tasks` ( `id` bigint unsigned NOT NULL AUTO_INCREMENT, `actionable_type` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `actionable_id` bigint unsigned NOT NULL, `actors` json NOT NULL, `property_id` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `title` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `description` text COLLATE utf8mb4_unicode_ci, `step` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `comparable_options` json DEFAULT NULL, `preview` longtext COLLATE utf8mb4_unicode_ci, `action_options` json DEFAULT NULL, `actor` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `selected_option` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `actor_comment` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `created_at` timestamp NULL DEFAULT NULL, `updated_at` timestamp NULL DEFAULT NULL, `queued_at` timestamp NULL DEFAULT NULL, `approvable_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `request` json DEFAULT NULL, PRIMARY KEY (`id`), KEY `pending_tasks_actionable_type_actionable_id_index` (`actionable_type`,`actionable_id`) ) ENGINE=MyISAM AUTO_INCREMENT=22 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
问题原因
MyISAM引擎的索引长度限制:MyISAM对联合索引的总长度有严格限制,最大仅支持1000字节。而你的表使用
utf8mb4字符集(每个字符占4字节),计算三个字段的索引长度总和:actionable_id(bigint):8字节actionable_type(varchar(191)):191×4=764字节step(varchar(191)):191×4=764字节
三者总长度为8+764+764=1536字节,远超MyISAM的1000字节上限,直接触发1071错误。
全局配置不适用MyISAM:你之前设置的
Schema::defaultStringLength(191)和InnoDB的DYNAMIC行格式,仅对InnoDB引擎生效。InnoDB在启用innodb_large_prefix后,联合索引最大支持3072字节,但这些规则不适用于MyISAM。错误SQL中的语法问题(
step后缺少闭合括号)属于次要问题,核心原因还是索引总长度超限。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

