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

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

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

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

    去掉重复的话就很简单了。
    lzz2394677796
        2
    lzz2394677796  
    OP
       2023-05-09 06:33:24 +08:00 via Android
    是要找出来
    levelworm
        3
    levelworm  
       2023-05-09 06:43:27 +08:00
    https://stackoverflow.com/questions/47095438/get-duplicate-records-from-a-large-table

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

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

    只是提供一个参考,不一定适合你们的业务
    HunterPan
        14
    HunterPan  
       2023-05-09 08:51:16 +08:00
    roarinmap
    scemsjyd
        15
    scemsjyd  
       2023-05-09 08:56:28 +08:00 via iPhone
    使用不同的哈希函数进行多次布隆过滤
    假如进行 10 次布隆过滤 10 次结果中都存在的大概率重复

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

    1.从数据库把 10 亿数据读取到磁盘上(因为内存中可能放不下)的一个文件中。
    2.根据装入内存大小限制,就这 1 个文件拆分成多个子文件。比如每个子文件存储 10 万条数据。
    3.一次读取每个子文件到内存进行排序,调用默认的排序算法升序排序即可,并保存。
    4.依次针对每 2 个子文件,一行行读取到内存执行归并排序,排序时找到了相同的行,就记录下来。
    5.将记录下来的那些行,编写 SQL 脚本更新数据库
    sujin190
        18
    sujin190  
       2023-05-09 09:44:21 +08:00
    @lzz2394677796 #9 50 亿 50 个表如果不是有序的话,group by 要连表估计难,其实最快的应该是用默认顺序读出来按序分堆到 5000 个文件,然后再单个文件处理找出重复就好了,如果内存充足的话直接读在内存算就好了啊,要啥 redis
    happyn
        19
    happyn  
       2023-05-09 10:01:53 +08:00
    不用那么麻烦,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  
       2023-05-09 10:05:31 +08:00
    脚本有点问题,修正下:

    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  
       2023-05-09 10:10:45 +08:00 via Android
    你是需要实时计算还是仅仅需要找出来?如果只是为了找出胀数据,那直接去从库执行 select x,count(1) from table group by x having count(1)>1 不就完事了。

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

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