截止目前,一共两千多粉丝,竟然99.36%是男僧。。。我果然是个不受女僧待见的人。
当然这个无所谓啦,毕竟作为一个三旬老汉,儿女双全,不该想的就不多想了。
为什么研究算法可以强身健体?答曰:年轻人精力旺盛,难免看点啥做点啥的伤身体,如果多拿出来点时间研究点算法,是不是用在不该用的方面时间就少了,对身体伤害也就少了,进而增强体质了?哦,挺有道理的样子。都搬个板凳过来默默的看我装A-C吧。哈哈
问题:
要做一个用户画像系统,维护用户的多个维度信息比如:性别,年龄,籍贯,身体,体重,手机型号,是否健身,饮食爱好。。。。。乱七八糟的可能有上万个维度(某些朋友别较真这合理不合理,就为了说明问题而已!以前写的文章还真有人非得跟我讨论我举的例子人家腾讯公司会不会真拿来做解决方案。。。。我了个去,身体伤的不轻,准是看多了,要节制),那么问题来了,如果我们用mysql数据保存这些的话,大约会是下面这个熊样:
我能力有限只写了4个属性,剩下的9996个属性大家自动脑补进去吧。好了,存储问题解决。来看检索:
10000个属性,写完了程序员也该老了,直接去办退休得了。执行效率如何?目测肯定慢的惊人。万一再复杂一点,来个distinct关键字。。。酸爽了。
Bitmap说明:
看来这方案玩不通了,怎么办?bitmap登场吧。
bitmap是位图算法,但是这个真的跟“图形”没多大关系哈。算法核心:用bit这个最小的存储单位(仅能表示0和1两个值)来构建算法,来表示很多信息,从而提高海量存储检索条件下的效率。
例子:
给10bit的内存空间,如何来表示9,5,2,7这4个数字?
- 非bitmap:
- 以java为例,表示一个整形最节约的是byte,每个整数8bit,显然完不成任务。别的short,int,long更别提了
- bitmap实现:
如上图,1-10这10个bit,黄颜色的赋值为1,其余赋值为0,好啦!任务完成。
有点奇技淫巧的既视感。
其实我们偷偷的加入了一个参数——bit位的位置或者说排序,最终我们赋值和位置(排序),来完成了标记。
(如果不好理解,可以想象成一个数组,每个位置都赋值1或者0,值为1的下标就是我们要保存的数字,这样通过赋值和数组的下标,构建成我们期望的结果)
问题解决方案:
上面我们简单的说明了什么是bitmap,现在来看如何解决我们开篇的问题:
用户画像需求,如果按照惯性思维肯定是“某人,拥有某属性1,属性2,属性3。。。。。”,立即一个mysql的table就设计出来了,刚才说了这方案有问题。我们转化一下思路——改为“某属性,被user1,user2,user3。。。。。拥有”,比如年龄33的用户有user1,user4,user9。。。。等等。套用上面的bitmap就是
如果我们有10亿用户,那么我们大不了把bit的位数提高到2的30次方。。。存储空间大约是1G而已。
总结:
本文不做过多的延伸,仅仅解释一下思路。
bitmap是空间利用率和检索效率最高的方式。当然在我们使用的过程中会有很多奇葩的关联需求出现,bitmap未必能全部解决,我后续还会针对bitmap写一些关联算法和优化,请持续关注。
谢谢各位。
福利图: