在遇到有关联关系 并且 数据量很大时,会遇到一个很头疼的问题,就是要处理的数据量太大,效率很低。
比如用户画像系统、每天的活跃用户、商品适配、人际关系 等。
以用户画像系统为例,如果用户数 < 500万 并且 标签数 也不多,可以用传统的关系型数据库直接查询。
但是当数据数很多 或者 查询比较复杂时,关系型数据会效率会很低。就得想想其它办法。
- 优化算法
- 数据压缩
- 压缩维度展示(类似数据压缩)
(1) 优化算法
用户画像系统
用户 张三、李四
用户标签 学生、单身、90后、程序员
统计 标签是90后 程序员 的用户
mysql条件查询
统计 标签是90后 或 程序员 的用户个数
mysql 查询 取并集
当 用户数过多 (500万用户) 或 标签过多(10万标签) 时,mysql的效率很低。
假设
user_id int类型,占4字节, 1千万用户 也就是 4 * 40 000 000 byte = 160M
user_name varchar(8) 使用utf-8编码 占24字节 也就是 24 * 40 000 000 byte = 480M
tag_id int类型,占4字节,10万标签 也就是 4 * 100000 byte = 400 000 = 400K
用户 和 标签 是多对多关系,假设有一张 用户标签表, 有1千万行 10万列, 每一行需要 (user_id + 100 000 tag_id ) * 4 byte * 10 000 000 ≈ 4000G
得换一种办法。
bitmap
一个标签对应多个用户
标签id化,用户id化 (倒排索引)
每个标签 一个bitmap ,这个bitmap存储了用户信息,用户是500万,实际存储需要 2^23 bit = 2^23 / 8 byte ≈ 1MB
有 10万标签 100 000 * 1MB = 100 GB
这个算的是所有的用户和标签,实际上可以只处理需要的。可以过滤掉很多用户和标签。
用户数过滤一部分,其实 一个bitmap 实际存储会变成 2^22 bit = 2^22 / 8 byte ≈ 0.5MB
只处理常用的标签,实际常用的大概1000,1000 * 0.5MB = 5G
根据标签查对应用户,拿到结果后 并集 交集 差集
统计 标签是90后 程序员 的用户
根据标签查对应用户,拿到结果后 交集
统计 标签是90后 或 程序员 的用户个数
根据标签查对应用户,拿到结果后 并集