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 命令创建带前缀的索引。
我需要在现有 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 命令创建带前缀的索引。