V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
nnegier
V2EX  ›  MySQL

MySQL max key length is 3072 bytes 伤心

  •  
  •   nnegier · 261 天前 · 3362 次点击
    这是一个创建于 261 天前的主题,其中的信息可能已经有所发展或是发生改变。

    报的错:
    ERROR 1071 (42000): Specified key was too long; max key length is 3072 bytes

    但我确实需要大一点的 key ,因为这里有个 key 是文件路径 filepath(varchar),怕有些路径逆天的长,所以才希望越大越好

    unique index xr_top_index(filepath,account)
    

    但是系统不允许,感觉这样的话只好作罢?

    24 条回复    2024-04-07 18:25:48 +08:00
    xenme
        1
    xenme  
       261 天前 via iPhone
    别放索引就好了,如果要按照文件路径来搜索,当文本来搜索,如果都是精确匹配是不是可以再存一个 hash 值作为索引
    zed1018
        2
    zed1018  
       261 天前   ❤️ 4
    要不考虑做个 hash 再用 key ?然后查询的时候用 hash ?
    dlmy
        3
    dlmy  
       261 天前
    弄个冗余字段,存 filepath 的 hash 值
    jorneyr
        4
    jorneyr  
       261 天前   ❤️ 1
    楼上的方案挺好,精确匹配就用 Hash ,部分匹配的话对 filepath 列增加全文索引。

    示例: 假设我们有一个表 articles ,其中包含 title 和 content 列,我们想要在这些列上创建全文索引。
    CREATE FULLTEXT INDEX idx_fulltext ON articles(title, content);
    rockyliang
        5
    rockyliang  
       261 天前
    可以考虑仅取 filepath 前面一部分的内容做索引,例如`ADD INDEX xr_top_index(filepath(200), account)`就是仅索引 filepath 前面 200 个字符
    Seulgi
        6
    Seulgi  
       261 天前
    说哈希的,你们没注意到人家是 unique 吗
    adoal
        7
    adoal  
       261 天前
    一定要用 MySQL 吗
    zed1018
        8
    zed1018  
       261 天前
    @Seulgi sha512 的碰撞概率已经极低了,要不然您觉得怎么办比较好。
    Seulgi
        9
    Seulgi  
       261 天前
    @zed1018 #8 不管你概率低不低,只要是 hash ,碰撞上了就是一个 bug ,他现在这个 path 是否能拆分,具体场景都没说清楚,给不了什么好办法。如果只是针对文件名,那么说明 path 对于索引来讲是无效的,然后考虑文件名是否有重复的可能,可以直接用文件名做索引。如果整个场景就是文件服务器,需要根据 path 去匹配某个文件夹下的所有文件夹和文件,可以考虑换数据库。
    ftsland
        10
    ftsland  
       261 天前
    可以加个缩写字段作为索引, 跟日志一样 , 把完整的路径调整为路径的首字母 /dir/www/something/file_123 -> /d/w/s/file_123
    qping
        11
    qping  
       261 天前
    @ftsland 和 hash 本质上没有区别,都是对路径进行了摘要
    tomwei7
        12
    tomwei7  
       261 天前
    可以尝试把 character 改成 binary 这样 filepath 可以设置到 varchar(3000) 左右,如果 character 是 utf8mb4 filepath 只能到 varchar(700) 左右
    june4
        13
    june4  
       261 天前
    @Seulgi 你竟然还在担心 hash 碰撞?不如担心流星把人类毁灭了可能性大一些
    zed1018
        14
    zed1018  
       261 天前   ❤️ 2
    @Seulgi #9 有限的预算,有限的需求做有限的方案,这是很正常的事情。绝大多数项目都是遇到了再说,最多再多冗余考虑一两步。人家上来提了这么一个问题,我们给了一个认为成本代价比较低的方案,您说了半天也没见给了什么有意义的东西(除了批判)。哪怕您在我们 hash 的方案基础上提是不是 hash key 不做 unique ,select 到多个结果以后在 coding 层面去对 path 做 equals ,那也是一种。
    wellerman
        15
    wellerman  
       261 天前
    @Seulgi 这个很好解决,rehash 呗。既然要精确,那插入时判断一下,hash 存在,路径不相等就 rehash 。
    Seulgi
        16
    Seulgi  
       261 天前
    @zed1018 #14 不知道哥们在急啥,我就说了一句没有注意到人家的 unique 吗,就我在批判了?我提出一个 hash 碰撞问题,就是在否认你们方案了?那可能你们在头脑风暴的时候只适合别人奉承你了。我没有随意给出方案的原因前面回复你了,因为题主场景并不详细,需要补充。针对两种详细的场景也给了方案。如果别人不认同,就是在批判你,那我觉得我们不适合讨论。直接 ban 就好了。
    laqow
        17
    laqow  
       261 天前
    默认 256 字符路径长度的 windows 惊了
    RobinzzZ
        18
    RobinzzZ  
       261 天前
    这问题我们也遇到过,直接改成不让用户建立层级那么深的目录了, 一般也用不着
    Rickkkkkkk
        19
    Rickkkkkkk  
       261 天前
    不允许呗.
    lisxour
        20
    lisxour  
       261 天前
    谁家好人的路径,3kb 都不够放啊
    guochao
        21
    guochao  
       261 天前
    存路径这个做法本身有点怪……我可能会选择文件的其他特征来做这个事情……

    不清楚场景,假设场景必须要存路径,考虑一下把 SOMEHASH(filepath, account), account 作为 key 呢?比如说 trigger 去 set 一下额外的列为 SHA2(CONCAT(filepath,"\\/", account), 256),把这个列作为 unique key 的一个 column 。降低碰撞概率的话,多加一种两种哈希呢?

    我是写业务的菜鸡,暂时还只能想怎么实现的问题。要不然就只能业务上限制一下了
    wenxueywx
        22
    wenxueywx  
       261 天前
    更好的做法是做好文件管理规划,程序上做约束,限制目录深度。
    leaflxh
        23
    leaflxh  
       261 天前
    b 站的图片都是 sha1 ,目前还没炸,当然可能是从数字 id 算出来的,提前预演跑一遍,确定没问题

    不放心的话存之前读一遍,判断是否有相同的哈希值
    xuyang2
        24
    xuyang2  
       261 天前
    GPT 如是说:

    SHA-1 (安全散列算法 1 )、SHA-256 和 SHA-512 都是加密散列函数,分别是 SHA 系列算法中的不同变种。碰撞( collision )指的是两个不同的输入值经过散列函数处理后产生相同的散列值。

    - SHA-1:SHA-1 产生的散列值是 160 位( 20 字节),理论上存在 2^160 个可能的散列值。根据生日攻击的原理,大约在尝试 2^(160/2) = 2^80 个不同的输入后,就有较大概率发生一次碰撞。然而,现实中,SHA-1 的实际安全性比理论值要低,现已发现更有效的攻击方法,使得找到 SHA-1 碰撞的实际难度远低于 2^80 次尝试。因此,SHA-1 不再被认为是安全的,很多应用已经逐渐废弃了 SHA-1 ,转而使用更安全的散列函数。
    - SHA-256:SHA-256 产生的散列值是 256 位( 32 字节),理论上存在 2^256 个可能的散列值。根据生日攻击原理,大约在尝试 2^(256/2) = 2^128 个不同的输入后,就有较大概率发生一次碰撞。目前没有已知的实用方法能有效地找到 SHA-256 的碰撞,因此它被认为是安全的。
    - SHA-512:SHA-512 产生的散列值是 512 位( 64 字节),理论上存在 2^512 个可能的散列值。根据生日攻击原理,大约在尝试 2^(512/2) = 2^256 个不同的输入后,就有较大概率发生一次碰撞。与 SHA-256 一样,目前没有已知的实用方法能有效地找到 SHA-512 的碰撞,所以它也被认为是安全的。

    需要注意的是,虽然理论上存在碰撞的可能性,但在实际中,对于 SHA-256 和 SHA-512 而言,找到碰撞所需要的计算量是极其巨大的,超出了目前技术的可行范围。因此,在实践中,它们被认为是足够安全的散列函数,广泛用于加密、数据完整性验证和数字签名等应用。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1024 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 21:30 · PVG 05:30 · LAX 13:30 · JFK 16:30
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.