mariadb 上的学说行为可翻译索引标识符太长

Posted

技术标签:

【中文标题】mariadb 上的学说行为可翻译索引标识符太长【英文标题】:doctrine-behaviors translatable index identifier too long on mariadb 【发布时间】:2018-12-24 13:28:24 【问题描述】:

我正在使用带有 flex 的 Symfony 4,并尝试使用 KNP Labs - Doctrine Behaviors 创建一些翻译表,但 Symfony 自动生成的索引名称对于 MariaDb 来说太长了。至少我从错误中理解了这一点:

在 AbstractmysqlDriver.php 第 125 行:

执行时发生异常

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]:语法错误或访问冲突:1071 指定 密钥太长;最大密钥长度为 767 字节

在 PDOConnection.php 第 109 行:

SQLSTATE[42000]:语法错误或访问冲突:1071 指定 密钥太长;最大密钥长度为 767 字节

在 PDOConnection.php 第 107 行:

SQLSTATE[42000]:语法错误或访问冲突:1071 指定 密钥太长;最大密钥长度为 767 字节

这里有些可疑,因为 MariaDb 规范是这么说的:

数据库、表、列、索引、约束、存储例程、 触发器、事件、视图、表空间、服务器和日志文件组具有 最大长度为 64 个字符。

我还不够先进,无法理解问题所在以及如何解决问题。 我的翻译表类如下:

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;
    

【问题讨论】:

我现在没时间,但简短的解释是使用utf8mb4 最大长度限制为 191 个字符。搜索一下你会发现很多关于这个的帖子,如果我没记错的话,这应该已经在 mysql 的最新版本中修复了。 @RickJames 好!我不明白你为什么提到我,但是以你的声誉,你应该知道你应该避免只链接答案,直接在你的答案中添加主要细节,对吗? :-)(链接仅供参考,可能会随着时间而改变)。 @gp_sflover - 是的,我因仅链接的答案而受到责备。但是我的 30 多个博客主要是为了提供这样的答案而设计的,这样我就可以更快地转到下一个问题。 Oracle 在消除我的博客方面做得很好。这个特殊的在 5.7 中被“淘汰”了,但我为那些没有升级的人保留了它。 (无论如何我都把它们放在身边。) 【参考方案1】:

767 错误的 5 种解决方法:http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes

如果您因为尝试使用 CHARACTER SET utf8mb4 而达到限制。然后执行以下操作之一(每个都有一个缺点)以避免错误:

⚈  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. 

或者... 保留 5.6/5.5/10.1,但执行 4 个步骤将限制提高到 3072 字节:

   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)

【讨论】:

如果可以的话,或者只是将 locale 长度更改为 191。 @ŁukaszJakubek - 这是第二个项目符号。

以上是关于mariadb 上的学说行为可翻译索引标识符太长的主要内容,如果未能解决你的问题,请参考以下文章

学说自定义 MariaDB 平台

zf2 + 学说 2 上的用户定义函数不起作用

MariaDB 5.5.60 上的奇怪零行为(双重)[重复]

由于选择性低(全为 NULL),MariaDB 不在 1 列自连接上使用索引

MariaDB10.2.6启用Mroonga存储引擎用于全文索引

MySQL / MariaDB InnoDB 索引停止工作