0

I'm using Symfony 4 with flex and tried to make some translation tables with the KNP Labs - Doctrine Behaviors but the index name auto generated by Symfony is too long for MariaDb. At least I understand this from the error:

In AbstractMySQLDriver.php line 125:

An exception occurred while executing

CREATE TABLE app_menu_trans (
    id INT AUTO_INCREMENT NOT NULL, 
    translatable_id INT DEFAULT NULL, 
    name VARCHAR(255 ) NOT NULL, 
    locale VARCHAR(255) NOT NULL, 
    INDEX IDX_B79696A62C2AC5D3 (trans latable_id), 
    UNIQUE INDEX app_menu_trans_unique_translation (translatable_id, locale), 
    PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_  

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t oo long; max key length is 767 bytes

In PDOConnection.php line 109:

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t oo long; max key length is 767 bytes

In PDOConnection.php line 107:

SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t oo long; max key length is 767 bytes

Something's fishy here, because MariaDb specs say that :

Databases, tables, columns, indexes, constraints, stored routines, triggers, events, views, tablespaces, servers and log file groups have an maximum length of 64 characters.

I'm not advanced enough to understand what is wrong and how to get around it.
My Translation Table class below:

namespace App\Entity;


use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;

/**
 * @ORM\Table(name="app_menu_trans")
 * @ORM\Entity
 */
class MenuTranslation
{
    use ORMBehaviors\Translatable\Translation;

    /**
     * @var string
     *
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * @param string $name
     *
     * @return MenuTranslationTranslation
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }
}
Rick James
  • 135,179
  • 13
  • 127
  • 222
Arkadiusz Galler
  • 305
  • 3
  • 18
  • 1
    I haven't the time now but the short explanation is that using `utf8mb4` the max length is limited to 191 chars. Searching a bit you will find tons of posts about this and if I remember well this should be already fixed in the last releases of mysql. – gp_sflover Jul 16 '18 at 23:51
  • 1
    @RickJames Good! I don't understand why you mentioned me but with your reputation you should know you should avoid only-link answers adding the main details directly in your answer right? :-) (_links are good only for reference and could change over time_). – gp_sflover Jul 17 '18 at 18:30
  • 1
    @gp_sflover - Yeah, I get chastised for link-only answers. But my 30+ blogs are designed primarily for providing answers like this, _so I can move on to the next question faster_. Oracle is doing a good job of obviating my blogs. This particular one is "eliminated" by 5.7, but I keep it around for those who have not upgraded. (I keep them all around anyway.) – Rick James Jul 17 '18 at 18:38

1 Answers1

1

5 workarounds for the 767 error: http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes

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 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; 
⚈  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)
Rick James
  • 135,179
  • 13
  • 127
  • 222