V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
lzz2394677796
V2EX  ›  问与答

求技术方案: mysql 存有 10 亿条不相同的手机号哈希值,现已知可能存在个别几条相同,如何找出

  •  
  •   lzz2394677796 · 351 天前 via Android · 2002 次点击
    这是一个创建于 351 天前的主题,其中的信息可能已经有所发展或是发生改变。
    求技术方案:mysql 存有 10 亿条不相同的手机号哈希值,现已知可能存在个别几条相同,如何找出

    group by count 大于 1 ?
    28 条回复    2023-05-09 11:59:04 +08:00
    T0m008
        1
    T0m008  
       351 天前
    是要找出来还是就去掉重复的就行了?

    去掉重复的话就很简单了。
    lzz2394677796
        2
    lzz2394677796  
    OP
       351 天前 via Android
    是要找出来
    levelworm
        3
    levelworm  
       351 天前
    https://stackoverflow.com/questions/47095438/get-duplicate-records-from-a-large-table

    不知道回答中的方法速度如何,不知道的确是你需要的。
    lzz2394677796
        4
    lzz2394677796  
    OP
       351 天前 via Android
    左手同事说,用 256g 内存进 redis 排查会快,什么意思?
    optional
        5
    optional  
       351 天前 via iPhone
    最后一通操作,还不如直接 group by count>1
    billgong
        6
    billgong  
       350 天前 via iPhone
    @lzz2394677796 那就和 mysql 没关系了,属于把数据读进内存然后再排查。redis 是内存数据库,速度当然快得多。但你得有条件(相当大的内存)才能跑得起装这么多数据的 redis 嘛,变相相当于蛮力跑了。
    qiayue
        7
    qiayue  
       350 天前
    分清楚是考察思维还是真实需求。
    如果是真实需求场景,一般在 10 亿级别的数据,肯定是分库分表了,那么找出重复的几条,这种属于鸡蛋里挑骨头的需求,建议不做。因为得不偿失,相对于去掉重复的几条之后的好处,需要花费的代价太大,所以根本没必要做。
    neptuno
        8
    neptuno  
       350 天前 via iPhone
    布隆过滤器试试
    lzz2394677796
        9
    lzz2394677796  
    OP
       350 天前
    @qiayue 是 1 亿条一个表,确切总量约 50 亿,蛮力也可以,只要找出来
    djoiwhud
        10
    djoiwhud  
       350 天前 via Android
    不知道我理解得对不对。

    没有保存手机明文?保存了就应该换加密方式。而不是试图剔除出碰撞的记录。
    lzz2394677796
        11
    lzz2394677796  
    OP
       350 天前
    @billgong 用 getsizeof 测算过内存开销,约 256g 能放进
    shakoon
        12
    shakoon  
       350 天前   ❤️ 1
    歪个话题。50 亿条手机号,全中国也没这么多。真收集了上亿手机号的企业,应该不会出现这种问题,不然这系统得多烂啊。所以,这真不是一个作业题?
    netnr
        13
    netnr  
       350 天前 via Android   ❤️ 1
    最近接触 ClickHouse 写入 1.5 亿日志,分批 100W/5s 写入速度,平均 20W/s
    50 亿大概要 7 小时,后面再查询统计就没得心智负担了,从根本上解决问题

    只是提供一个参考,不一定适合你们的业务
    HunterPan
        14
    HunterPan  
       350 天前
    roarinmap
    scemsjyd
        15
    scemsjyd  
       350 天前 via iPhone
    使用不同的哈希函数进行多次布隆过滤
    假如进行 10 次布隆过滤 10 次结果中都存在的大概率重复

    个人想法如有不对请指正
    hhjswf
        16
    hhjswf  
       350 天前 via Android
    允许误差吗?可以的话,用布隆过滤器?
    H0H
        17
    H0H  
       350 天前
    这种有啥难的。这一看就是只要找出来处理掉即可,并没有要求实时的瞬间查询出结果。

    1.从数据库把 10 亿数据读取到磁盘上(因为内存中可能放不下)的一个文件中。
    2.根据装入内存大小限制,就这 1 个文件拆分成多个子文件。比如每个子文件存储 10 万条数据。
    3.一次读取每个子文件到内存进行排序,调用默认的排序算法升序排序即可,并保存。
    4.依次针对每 2 个子文件,一行行读取到内存执行归并排序,排序时找到了相同的行,就记录下来。
    5.将记录下来的那些行,编写 SQL 脚本更新数据库
    sujin190
        18
    sujin190  
       350 天前
    @lzz2394677796 #9 50 亿 50 个表如果不是有序的话,group by 要连表估计难,其实最快的应该是用默认顺序读出来按序分堆到 5000 个文件,然后再单个文件处理找出重复就好了,如果内存充足的话直接读在内存算就好了啊,要啥 redis
    happyn
        19
    happyn  
       350 天前
    不用那么麻烦,10 亿手机号,导出个 txt ;然后 就想楼上说的,多拆分几个子文件,分别排序再合并,最后用 uniq -d 查一下就可以;

    脚本示例:
    split -l 1000000000 huge-file small-chunk
    for X in small-chunk*; do sort -u < $X > sorted-$X; done
    sort -u -m sorted-small-chunk* > sorted-huge-file && rm -rf small-chunk* sorted-small-chunk*

    cat sorted-huge-file|uniq -d
    happyn
        20
    happyn  
       350 天前
    脚本有点问题,修正下:

    split -l 1000000000 huge-file small-chunk
    for X in small-chunk*; do sort -o sorted-$X $X; done
    sort -m sorted-small-chunk* > sorted-huge-file

    cat sorted-huge-file|uniq -d
    sadfQED2
        21
    sadfQED2  
       350 天前 via Android
    你是需要实时计算还是仅仅需要找出来?如果只是为了找出胀数据,那直接去从库执行 select x,count(1) from table group by x having count(1)>1 不就完事了。

    如果你需要线上业务实时计算的话,那就上实时计算引擎,比如楼上说的 clickhouse ,或者 starrocks 之类的。你这样业务,实时计算引擎能够几百毫秒出结果
    amon
        22
    amon  
       350 天前
    如果只为了找出来,group by having 即可。
    如果是为了面试,请将你知道的所有技术名词试着用通顺的逻辑组合在一起即可。
    mmuggle
        23
    mmuggle  
       350 天前
    bitmap
    sujin190
        24
    sujin190  
       350 天前
    @sadfQED2 #21
    @amon #22 不要忽略数据量的问题,之前搞过这种查询方便就把大量数据合并到一个表,数据文件数百 G ,内存 16G ,然后查询的时候发现 mysql 读磁盘才 10M 不到,加上查询过程中临时文件的 IO ,扔一个 sql 进去跑几个小时啥结果没有。。
    swulling
        25
    swulling  
       350 天前 via iPhone
    dump 出来用 awk 一行就搞定了。时间复杂度是 O ( 1 )。不用 awk 随便找个语言用 HashMap 就行了。

    用 sort 的不知道是咋想的。
    JKeita
        26
    JKeita  
       350 天前
    用 bitmap
    Chad0000
        27
    Chad0000  
       350 天前
    如果只是偶尔需要排查的话,那么可以将 50 亿数据分组,比如按前两位字母。这样每次只算一组,直接在内存中计算,不需要那么大内存。
    lzz2394677796
        28
    lzz2394677796  
    OP
       350 天前
    不是面试。索引后总数据库文件约 300G 。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1210 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 23:11 · PVG 07:11 · LAX 16:11 · JFK 19:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.