Search code examples
mysqlspringeclipselinkmariadb

MariaDB Character Encoding


I have just started to port an older MySQL/Spring/Eclipselink project to MariaDB. I am encountering an issue with table creation that can be demonstrated as follows:

MariaDB [spasm]> CREATE TABLE Configuration (ID BIGINT NOT NULL, Attribute VARCHAR(190) NOT NULL UNIQUE, Value VARCHAR(255) NOT NULL, PRIMARY KEY (ID));
Query OK, 0 rows affected (0.07 sec)

MariaDB [spasm]> drop table Configuration;
Query OK, 0 rows affected (0.06 sec)

MariaDB [spasm]> CREATE TABLE Configuration (ID BIGINT NOT NULL, Attribute VARCHAR(255) NOT NULL UNIQUE, Value VARCHAR(255) NOT NULL, PRIMARY KEY (ID));
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
MariaDB [spasm]> 

MariaDB [spasm]> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8mb4                    |
| character_set_connection | utf8mb4                    |
| character_set_database   | utf8mb4                    |
| character_set_filesystem | binary                     |
| character_set_results    | utf8mb4                    |
| character_set_server     | utf8mb4                    |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

I understand that this is related to character encoding, however I don't know how to manage/correct it?


Solution

  • The new default CHARACTER SET is utf8mb4. It is complaining about the UNIQUE index:

    Attribute VARCHAR(255) NOT NULL UNIQUE
    

    If you are hitting the limit because of trying to use CHARACTER SET utf8mb4. Then do one of the following (each has a drawback) to avoid the error:

    ⚈  Upgrade to 5.7.7 (MariaDB 10.2.2?) for 3072 byte limit -- your cloud may not provide this; 
    ⚈  Change 255 to 191 on the VARCHAR -- you lose any values longer than 191 characters (unlikely?); 
    ⚈  ALTER .. CONVERT TO utf8 -- you lose Emoji and some of Chinese; 
    ⚈  Use a "prefix" index -- you lose some of the performance benefits. 
    

    Or... Stay with 5.6/5.5/10.1 but perform 4 steps to raise the limit to 3072 bytes:

    SET GLOBAL innodb_file_format=Barracuda;
    SET GLOBAL innodb_file_per_table=1;
    SET GLOBAL innodb_large_prefix=1;
    logout & login (to get the global values);
    ALTER TABLE tbl ROW_FORMAT=DYNAMIC;  -- (or COMPRESSED)