指定的密钥太长;使用 knex 的最大密钥长度为 767 字节

Specified key was too long; max key length is 767 bytes using knex

我创建了以下交易:

exports.up = async (knex, Promise) => (await knex.schema.hasTable('settings'))
    ? null
    : knex.schema.createTable('settings', function (table) {
        table.increments('id')
        table.string('name').notNullable().unique()
        table.string('value').notNullable()

        table.primary('name')
    }).then(() => {
        return knex('settings').insert([
            { name: 'sandbox', value: 'off'},
            { name: 'promo', value: 'off'}
        ]);
    });

exports.down = async (knex, Promise) => (await knex.schema.hasTable('settings'))
    ? knex.schema.dropTable('settings')
    : null

本质上,我正在尝试创建一个 settings table,它定义了两个主键,一个 id 和一个 name。问题是我得到这个错误:

migration failed with error: alter table settings add unique settings_name_unique(name) - Specified key was too long; max key length is 767 bytes

我该如何解决?

Specified key was too long; max key length is 767 bytes 来自 MySQL 并且是 explained in this answer。 knex 中 string 的默认长度为 255。对于四字节 utf8mb4 字符,这是 1,020 字节。是的,这很烦人。

您可以通过 using the dynamic row format 解决此问题。这是自 5.7.9 以来新表的默认设置,因此您也可以考虑升级 MySQL.

或者您可以为字符串设置一个较低的最大长度。您可以通过将长度传递给 string 来完成此操作。使用四个字节字符,即 767 / 4 = 191 个字符。

table.string('name', 191).notNullable().unique()