UTF8 mysql 数据库中超过 255 个字符的键

Key longer than 255 chars in a UTF8 mysql database

我需要在现有 Django/South/MySQL 应用程序中存储 URL 超过 255 个字符。这些 URLs 用作外键。问题是排序规则是 UTF8,所以如果我将 URL 字段的 max_length 增加到 512,我会收到以下错误:

'Specified key was too long; max key length is 767 bytes'

我想原因是在 UTF8 中,每个字符可能有 3 个字节长,所以即使只有 256 个字符,我也可以超过限制。

由于 URL 应该只包含 ASCII 字符,我尝试在(数据)迁移中将特定 table 的排序规则更改为 ASCII,并且它似乎运行良好:迁移后,我可以在后续的模式迁移中成功地将 max_length 更改为 512 并存储更长的 URLs.

但是,在引导数据库时,我遇到了一个问题,它试图在不进行迁移的情况下设置数据库:

syncdb --all
migrate --fake

syncdb,当然会失败,因为它再次尝试创建太长的外键(迁移以调整数据库的排序规则不是 运行)。

如果我在没有 --all 的情况下同步数据库(然后 运行 没有 --fake 的迁移),它会失败并指出某些身份验证 table 不存在。

知道增加 max_length 限制的正确方法吗?

最好的,也可能是唯一的解决方案:根本不要将 url 用作外键。

将 url 放在 table 和 surrogate key 中(例如,自动递增整数)。将该键用于外键,并在 url 列上放置一个唯一索引以防止重复 urls.

我采用的侵入性较小且不太干净的方法是:

  • 使用indexes with prefix size。这只能在迁移中使用原始 SQL 语句来完成。
  • 由于在设置新数据库时通常不会运行迁移,所以我创建了一个创建索引的管理命令,此命令必须在运行 syncdb 和 migrate 之后:

    ./manage.py syncdb --all
    ./manage.py migrate --fake
    ./manage.py create_indexes
    

myapp/management/commands/create_indexes.py 是一个管理命令,运行 原始 SQL 命令创建带前缀的索引。