首页 > 解决方案 > 当我尝试在 C 面板 phpmyadmin 中导入 sql 文件时 - 指定的密钥太长;最大密钥长度为 767 字节 #1071

问题描述

有一些类似的问题,但不是我真正想要的。我怎样才能增加这个限制。什么是文件目标我可​​以在哪里用另一个替换这个数字(767 字节)。

-- Dumping structure for table jofr.categories
CREATE TABLE IF NOT EXISTS `categories` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `parent_id` int(10) unsigned DEFAULT NULL,
  `order` int(11) NOT NULL DEFAULT '1',
  `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `slug` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `categories_slug_unique` (`slug`),
  KEY `categories_parent_id_foreign` (`parent_id`),
  CONSTRAINT `categories_parent_id_foreign` FOREIGN KEY (`parent_id`) REFERENCES `categories` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
MySQL said: Documentation

#1071 - Specified key was too long; max key length is 767 bytes

标签: laravelphpmyadmin

解决方案


这是 MySQL InnoDB 限制,而不是 PHP 限制。您只能使用代码解决限制,或者您可以使用数据库选项潜在地增加限制。

问题出在您的索引上slugslug定义为 255 个字符,并且您使用的是 utf8mb4,每个字符使用 4 个字节,因此您的索引slug需要 1020 个字节。

有几个解决方法选项。

1. 缩小你的领域。

与其制作slug255 个字符,不如将其设为 191. 191 * 4 = 764 < 767。您可以通过在迁移中指定字段长度或不指定\Illuminate\Support\Facades\Schema::defaultStringLength(191);其他人提到的长度和设置来做到这一点。

2. 减小索引的大小。

您可以将字段大小保持在 255,但告诉 MySQL 仅索引前 191 个字符。我不知道 Laravel 迁移是否支持这一点,但你可以随时尝试。

$table->index('slug(191)');

innodb_large_prefix3.使用动态行格式启用数据库选项。

数据库选项将innodb_large_prefix密钥长度限制增加到 3072 字节。但是,此选项仅影响行格式为 DYNAMIC 或 COMPRESSED 的表。

如果您使用的是 MySQL >= 5.7.7,则innodb_large_prefix默认情况下启用该选项。

如果您使用的是 MySQL >= 5.7.9,则默认行格式为 DYNAMIC,并且该innodb_large_prefix选项默认启用,因此您不会遇到此问题,除非您更改了默认设置。

如果你在 MySQL < 5.7.9 上,默认的行格式是 COMPACT,所以你需要弄清楚如何告诉 Laravel 使用 DYNAMIC 行格式。如果要对所有表执行此操作,可以'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',在数据库配置中进行设置。如果您只想对一张表执行此操作,则需要在迁移文件中运行原始 DB 创建语句。

参考:
MySQL 创建索引文档- 有关键大小、行格式和部分索引的信息
MySQL innodb_large_prefix 选项
MySQL innodb_default_row_format 选项


推荐阅读