You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

问题原因

  1. 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错误。
  2. 全局配置不适用MyISAM:你之前设置的Schema::defaultStringLength(191)和InnoDB的DYNAMIC行格式,仅对InnoDB引擎生效。InnoDB在启用innodb_large_prefix后,联合索引最大支持3072字节,但这些规则不适用于MyISAM。

  3. 错误SQL中的语法问题(step后缺少闭合括号)属于次要问题,核心原因还是索引总长度超限。

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 08:22:41