MySQL string fields used to be stored in the utf8
character set and are now stored using the utf8mb4
character set.
Due to an InnoDB limitation, such fields with primary keys or unique indexes now have a maximum length of 191 characters. To work around this, either:
- shorten the length of the field to 191 characters or less
- drop the unique constraint and use an entity-level unique constraint instead
- or use the
varchar_ascii
storage format
Just to illustrate, assuming we have the following field defined in hook_schema()
:
$schema['fields']['foo'] = array(
'description' => 'Foo',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
);
$schema['unique keys'][] = arrray('foo');
This schema definition will throw an error on new installs due to the InnoDB limitation. To work around this, we could either change the type
key from varchar
to varchar_ascii
, or change the length
key from 255 to 191.
Alternatively, if the field is defined in a BaseFieldDefinition
as a string:
$fields['menu_name'] = BaseFieldDefinition::create('string')
->setLabel(t('Menu name'))
->setDescription(t('The menu name. All links with the same menu name (such as "tools") are part of the same menu.'))
->setSetting('max_length', 255)
->setDefaultValue('tools');
In this case we can use setSetting('is_ascii', TRUE)
if the field is an ASCII-only machine name and we want to use the full 255 characters, or setSetting('max_length', 191)
to keep the UTF-8 encoding and reduce the length of the field.