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

2023-05-09 06:16:21 +08:00
 lzz2394677796
求技术方案:mysql 存有 10 亿条不相同的手机号哈希值,现已知可能存在个别几条相同,如何找出

group by count 大于 1 ?
2224 次点击
所在节点    问与答
28 条回复
T0m008
2023-05-09 06:31:17 +08:00
是要找出来还是就去掉重复的就行了?

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

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

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

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

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

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

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/938445

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX