2015-06-21 61 views
0

我需要在现有的Django/South/MySQL应用程序中存储超过255个字符的URL。这些URL被用作外键。问题是,对照为UTF8,所以如果我增加URLField,比方说,512的MAX_LENGTH,我收到以下错误:UTF8 mysql数据库中长于255个字符的关键字

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

我猜的原因是,在UTF8,每个角色可以可能有3个字节长,所以即使只有256个字符,我也可以超过极限。因为URL只能包含ASCII字符,所以我尝试在(数据)迁移中将特定表的排序顺序更改为ASCII,并且它看起来效果不错:迁移后,我可以成功地将max_length更改为512 in随后的模式迁移并存储更长的URL。

然而自举数据库的时候,我有,它试图建立数据库,而无需通过迁移去的问题:

syncdb --all 
migrate --fake 

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

如果我在没有--all的情况下运行syncdb(然后运行没有--fake的迁移),它会失败,说一些认证表不存在。

任何想法的正确方法来增加max_length限制?

回答

4

最好的,也许只有解决方案:不要使用URL作为外键。

将网址置于surrogate key(例如自动递增整数)的表格中。使用该键作为外键,并在url列上设置唯一索引以防止重复的url。

+0

这绝对是一个更好的设计。如果考虑执行连接所需的总计算,请考虑存储768个字符的字符串所需的位数与整数之间的关系。然后想想计算机必须做什么来匹配两者之间的平等:https://dev.mysql.com/doc/refman/5.7/en/storage-requirements.html – FlipperPA

+0

非常感谢分享。 – Sylvain

0

一个创伤小,不干净的方法,我把是:

  • 使用indexes with prefix size。这只能在迁移中使用原始SQL语句完成。
  • 由于建立新数据库时迁移通常不跑,我做它创建索引的管理命令,这个命令必须执行syncdb后运行和迁移:

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

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