广告
返回顶部
首页 > 资讯 > 数据库 >MySQL位图索引如何解决用户画像问题
  • 342
分享到

MySQL位图索引如何解决用户画像问题

2024-04-02 19:04:59 342人浏览 泡泡鱼
摘要

这篇文章主要介绍了Mysql位图索引如何解决用户画像问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。用户画像的原始表,有一亿记录,100多

这篇文章主要介绍了Mysql位图索引如何解决用户画像问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

用户画像的原始表,有一亿记录,100多个维度(100多个列),比如年龄,性别,爱好,是否有车,是否有房什么的.

测试环境800w数据,大概在5G左右

需要解决的问题一 :在100列中任选N列,过滤查询,执行时间小于一秒。实际上N一般在5到10

即类似

select * from 画像表 where 性别=‘男’ and 年龄 between 20 and 30 and 有车='yes' and 有房='yes' and 已婚='no'

问题二:全体数据的随意聚合,执行时间小于5秒

比如

select 年龄,性别,count(*) from 画像表 group by 年龄,性别

数据库解决这个问题有一些麻烦,传统建索引优化的方式不起作用了。

100多个列随意选择几列查询,索引不可能提前建出这么多.

先看测试数据

CREATE TABLE `o_huaxiang_big` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) DEFAULT NULL,
  `umc_sex` varchar(20) DEFAULT NULL,
  `age` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ;

MySQL位图索引如何解决用户画像问题

处理这个问题,我自然想到模拟一个位图.

一般画像数据有几种类型

1.数值类型

2.日期类型

3.日期时间类型

4.字符串类型

其中 日期和字符串类型可以作为离散值,

日期时间类型也可以转化为日期类型,作为离散值处理。

数值类型比较麻烦,需要人为介入判断是否是离散值,如果不是还需要划分范围。

总之,所有的值都要映射为离散值

然后以上图前5个数据为例,将离散值映射为位图

男      0 0 0 0 1

未知   1 0 0 1 0

女      0  1 1 0 0

一个bigint 是8字节的,为了取整,我存放60个记录的位信息。

然后建位图表如下

CREATE TABLE `bitmap20` (
  `table_name` varchar(32) NOT NULL DEFAULT '' comment '位图表记录的原始表名称',
  `column_name` varchar(32) NOT NULL DEFAULT '' comment '列名称',
  `min_id` int(11) DEFAULT NULL comment '起始ID',
  `max_id` int(11) DEFAULT NULL comment '终止ID',
  `gid` int(11) NOT NULL DEFAULT '0' comment '分组ID,每组1200记录' ,
  `grouped` varchar(32) NOT NULL DEFAULT '' comment '离散值',
  `total` bigint(21) NOT NULL DEFAULT '0' comment '总数',
  `c20` bigint(20) NOT NULL DEFAULT '0',
  `c19` bigint(20) NOT NULL DEFAULT '0',
  `c18` bigint(20) NOT NULL DEFAULT '0',
  `c17` bigint(20) NOT NULL DEFAULT '0',
  `c16` bigint(20) NOT NULL DEFAULT '0',
  `c15` bigint(20) NOT NULL DEFAULT '0',
  `c14` bigint(20) NOT NULL DEFAULT '0',
  `c13` bigint(20) NOT NULL DEFAULT '0',
  `c12` bigint(20) NOT NULL DEFAULT '0',
  `c11` bigint(20) NOT NULL DEFAULT '0',
  `c10` bigint(20) NOT NULL DEFAULT '0',
  `c9` bigint(20) NOT NULL DEFAULT '0',
  `c8` bigint(20) NOT NULL DEFAULT '0',
  `c7` bigint(20) NOT NULL DEFAULT '0',
  `c6` bigint(20) NOT NULL DEFAULT '0',
  `c5` bigint(20) NOT NULL DEFAULT '0',
  `c4` bigint(20) NOT NULL DEFAULT '0',
  `c3` bigint(20) NOT NULL DEFAULT '0',
  `c2` bigint(20) NOT NULL DEFAULT '0',
  `c1` bigint(20) NOT NULL DEFAULT '0',
  PRIMARY KEY (`column_name`,`gid`,`grouped`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED comment '位图表';

c1-c20,一共20个bigint类型的字段,每个bigint记录60个位信息。

也就是位图表每行存储1200个原始记录的位图信息,并且位图表启用了压缩。

测试环境

4C 8G内存(innodb buffer 2G) SSD硬盘

800万原始画像数据,占用硬盘5G

初始化位图表

insert into bitmap20 
select 
  'o_huaxiang_big' table_name,
  'umc_sex' column_name,
  ((g1200-1)*60)*20 min_id,
  ((g1200-1)*60)*20+1200 max_id,
  v2.*
from (
	select 
	g1200,
	grouped,
	sum(total) total, 
	ifnull(max(case when abs((g1200-1)*20-g60)=20 then bitmap else null end),0) c20,
	ifnull(max(case when abs((g1200-1)*20-g60)=19 then bitmap else null end),0) c19,
	ifnull(max(case when abs((g1200-1)*20-g60)=18 then bitmap else null end),0) c18,
	ifnull(max(case when abs((g1200-1)*20-g60)=17 then bitmap else null end),0) c17,
	ifnull(max(case when abs((g1200-1)*20-g60)=16 then bitmap else null end),0) c16,
	ifnull(max(case when abs((g1200-1)*20-g60)=15 then bitmap else null end),0) c15,
	ifnull(max(case when abs((g1200-1)*20-g60)=14 then bitmap else null end),0) c14,
	ifnull(max(case when abs((g1200-1)*20-g60)=13 then bitmap else null end),0) c13,
	ifnull(max(case when abs((g1200-1)*20-g60)=12 then bitmap else null end),0) c12,
	ifnull(max(case when abs((g1200-1)*20-g60)=11 then bitmap else null end),0) c11,
	ifnull(max(case when abs((g1200-1)*20-g60)=10 then bitmap else null end),0) c10,
	ifnull(max(case when abs((g1200-1)*20-g60)=9 then bitmap else null end),0) c9,
	ifnull(max(case when abs((g1200-1)*20-g60)=8 then bitmap else null end),0) c8,
	ifnull(max(case when abs((g1200-1)*20-g60)=7 then bitmap else null end),0) c7,
	ifnull(max(case when abs((g1200-1)*20-g60)=6 then bitmap else null end),0) c6,
	ifnull(max(case when abs((g1200-1)*20-g60)=5 then bitmap else null end),0) c5,
	ifnull(max(case when abs((g1200-1)*20-g60)=4 then bitmap else null end),0) c4,
	ifnull(max(case when abs((g1200-1)*20-g60)=3 then bitmap else null end),0) c3,
	ifnull(max(case when abs((g1200-1)*20-g60)=2 then bitmap else null end),0) c2,
	ifnull(max(case when abs((g1200-1)*20-g60)=1 then bitmap else null end),0) c1
	 from (
		SELECT 
			CEIL(id / 60) g60,
			CEIL(id / 1200) g1200,
			umc_sex grouped,
			COUNT(*) total,
			BIT_OR(1 << (MOD(id, 60))) bitmap
		FROM
			o_huaxiang_big o
		GROUP BY g1200 , g60 , umc_sex
	) v1 group by  g1200,grouped
) v2;
 
insert into bitmap20 
select 
  'o_huaxiang_big' table_name,
  'age' column_name,
    ((g1200-1)*60)*20 min_id,
    ((g1200-1)*60)*20+1200 max_id,
  v2.*
from (
	select 
	g1200,
	grouped,
	sum(total) total, 
	ifnull(max(case when abs((g1200-1)*20-g60)=20 then bitmap else null end),0) c20,
	ifnull(max(case when abs((g1200-1)*20-g60)=19 then bitmap else null end),0) c19,
	ifnull(max(case when abs((g1200-1)*20-g60)=18 then bitmap else null end),0) c18,
	ifnull(max(case when abs((g1200-1)*20-g60)=17 then bitmap else null end),0) c17,
	ifnull(max(case when abs((g1200-1)*20-g60)=16 then bitmap else null end),0) c16,
	ifnull(max(case when abs((g1200-1)*20-g60)=15 then bitmap else null end),0) c15,
	ifnull(max(case when abs((g1200-1)*20-g60)=14 then bitmap else null end),0) c14,
	ifnull(max(case when abs((g1200-1)*20-g60)=13 then bitmap else null end),0) c13,
	ifnull(max(case when abs((g1200-1)*20-g60)=12 then bitmap else null end),0) c12,
	ifnull(max(case when abs((g1200-1)*20-g60)=11 then bitmap else null end),0) c11,
	ifnull(max(case when abs((g1200-1)*20-g60)=10 then bitmap else null end),0) c10,
	ifnull(max(case when abs((g1200-1)*20-g60)=9 then bitmap else null end),0) c9,
	ifnull(max(case when abs((g1200-1)*20-g60)=8 then bitmap else null end),0) c8,
	ifnull(max(case when abs((g1200-1)*20-g60)=7 then bitmap else null end),0) c7,
	ifnull(max(case when abs((g1200-1)*20-g60)=6 then bitmap else null end),0) c6,
	ifnull(max(case when abs((g1200-1)*20-g60)=5 then bitmap else null end),0) c5,
	ifnull(max(case when abs((g1200-1)*20-g60)=4 then bitmap else null end),0) c4,
	ifnull(max(case when abs((g1200-1)*20-g60)=3 then bitmap else null end),0) c3,
	ifnull(max(case when abs((g1200-1)*20-g60)=2 then bitmap else null end),0) c2,
	ifnull(max(case when abs((g1200-1)*20-g60)=1 then bitmap else null end),0) c1
	 from (
		SELECT 
			CEIL(id / 60) g60,
			CEIL(id / 1200) g1200,
			age grouped,
			COUNT(*) total,
			BIT_OR(1 << (MOD(id, 60))) bitmap
		FROM
			o_huaxiang_big o
		GROUP BY g1200 , g60 , age
	) v1 group by  g1200,grouped
) v2;

性别和年龄的初始化分别耗时36秒和49秒

两个维度的索引占用磁盘40M

聚合查询,800万数据耗时1.7秒.因为是CPU密集型操作,io非常小,所以可以通过多线程再优化.

select t1p,t2p,sum(total) 
from (
 select 
  t1.grouped t1p,
  t2.grouped t2p,
  bit_count(t1.c1&t2.c1) +
  bit_count(t1.c2&t2.c2) +
  bit_count(t1.c3&t2.c3) +
  bit_count(t1.c4&t2.c4) +
  bit_count(t1.c5&t2.c5) +
  bit_count(t1.c6&t2.c6) +
  bit_count(t1.c7&t2.c7) +
  bit_count(t1.c8&t2.c8) +
  bit_count(t1.c9&t2.c9) +
  bit_count(t1.c10&t2.c10) +
  bit_count(t1.c11&t2.c11) +
  bit_count(t1.c12&t2.c12) +
  bit_count(t1.c13&t2.c13) +
  bit_count(t1.c14&t2.c14) +
  bit_count(t1.c15&t2.c15) +
  bit_count(t1.c16&t2.c16) +
  bit_count(t1.c17&t2.c17) +
  bit_count(t1.c18&t2.c18) +
  bit_count(t1.c19&t2.c19) +
  bit_count(t1.c20&t2.c20)    total
  from   
  bitmap20 t1 
  inner join    
  bitmap20 t2
  on(t1.gid=t2.gid)
  where  t1.column_name='umc_sex' and  t2.column_name='age' 
) t3 where total>0 group by t1p,t2p

还有一个问题是过滤

select    max_id ,
concat(
	concat(right(c20,1),left(c20,59)) ,
	concat(right(c19,1),left(c19,59)) ,
	concat(right(c18,1),left(c18,59)) ,
	concat(right(c17,1),left(c17,59)) ,
	concat(right(c16,1),left(c16,59)) ,
	concat(right(c15,1),left(c15,59)) ,
	concat(right(c14,1),left(c14,59)) ,
	concat(right(c13,1),left(c13,59)) ,
	concat(right(c12,1),left(c12,59)) ,
	concat(right(c11,1),left(c11,59)) ,
	concat(right(c10,1),left(c10,59)) ,
	concat(right(c9,1),left(c9,59)) ,
	concat(right(c8,1),left(c8,59)) ,
	concat(right(c7,1),left(c7,59)) ,
	concat(right(c6,1),left(c6,59)) ,
	concat(right(c5,1),left(c5,59)) ,
	concat(right(c4,1),left(c4,59)) ,
	concat(right(c3,1),left(c3,59)) ,
	concat(right(c2,1),left(c2,59)) ,
	concat(right(c1,1),left(c1,59)) 
)  
c
from (
	select gid,min_id,max_id, 
	lpad(conv(bit_and(c20),10,2),60,'0') c20,
	lpad(conv(bit_and(c19),10,2),60,'0') c19,
	lpad(conv(bit_and(c18),10,2),60,'0') c18,
	lpad(conv(bit_and(c17),10,2),60,'0') c17,
	lpad(conv(bit_and(c16),10,2),60,'0') c16,
	lpad(conv(bit_and(c15),10,2),60,'0') c15,
	lpad(conv(bit_and(c14),10,2),60,'0') c14,
	lpad(conv(bit_and(c13),10,2),60,'0') c13,
	lpad(conv(bit_and(c12),10,2),60,'0') c12,
	lpad(conv(bit_and(c11),10,2),60,'0') c11,
	lpad(conv(bit_and(c10),10,2),60,'0') c10,
	lpad(conv(bit_and(c9),10,2),60,'0')  c9,
	lpad(conv(bit_and(c8),10,2),60,'0')  c8,
	lpad(conv(bit_and(c7),10,2),60,'0')  c7,
	lpad(conv(bit_and(c6),10,2),60,'0')  c6,
	lpad(conv(bit_and(c5),10,2),60,'0')  c5,
	lpad(conv(bit_and(c4),10,2),60,'0')  c4,
	lpad(conv(bit_and(c3),10,2),60,'0')  c3,
	lpad(conv(bit_and(c2),10,2),60,'0')  c2,
	lpad(conv(bit_and(c1),10,2),60,'0')  c1
	from bitmap20 
	 where (
	(column_name='umc_sex' and grouped='未知') or 
	(column_name='age' and grouped='117'))  
	group by gid,min_id,max_id having count(distinct column_name)=2 
) v1

用max_id 减去  ‘1’在c字符串的位置,就是原始的ID

感谢你能够认真阅读完这篇文章,希望小编分享的“mysql位图索引如何解决用户画像问题”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网数据库频道,更多相关知识等着你来学习!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL位图索引如何解决用户画像问题

本文链接: https://www.lsjlt.com/news/63172.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL位图索引如何解决用户画像问题
    这篇文章主要介绍了MySQL位图索引如何解决用户画像问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。用户画像的原始表,有一亿记录,100多...
    99+
    2022-10-18
  • 如何使用MySQL位图索引解决用户画像问题
    这篇文章给大家分享的是有关如何使用MySQL位图索引解决用户画像问题的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。每个bigint类型包括60个记录的位信息.但是第0位表示第六十...
    99+
    2022-10-18
  • 如何解决MySQL中一个双引号的错位问题
    这篇文章主要讲解了“如何解决MySQL中一个双引号的错位问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“如何解决MySQL中一个双引号的错位问题”吧!&n...
    99+
    2022-10-18
  • 如何解决MySQL中因一个双引号错位引发的问题
    小编给大家分享一下如何解决MySQL中因一个双引号错位引发的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、前言最近经常碰...
    99+
    2022-10-18
  • 如何解决MySQL批量插入和唯一索引问题
    这篇文章主要介绍了如何解决MySQL批量插入和唯一索引问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。MySQL批量插入问题在开发项目时,...
    99+
    2022-10-18
  • 如何解决MySql整型索引和字符串索引失效或隐式转换问题
    这篇文章主要为大家展示了“如何解决MySql整型索引和字符串索引失效或隐式转换问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何解决MySql整型索引和字符串索引失效或隐式转换问题”这篇文章...
    99+
    2023-06-25
  • 如何解决mysql删除用户的bug问题
    这篇文章将为大家详细讲解有关如何解决mysql删除用户的bug问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。删除了user的用户之后 无法再次创造相同的用户名在mysql 数据库中有一张user表,可...
    99+
    2023-06-14
  • 如何使用PHP索引对象解决LeetCode算法问题?
    LeetCode算法问题是很多程序员都会遇到的挑战,而使用PHP索引对象是解决这些问题的一种有效方法。在本文中,我们将探讨如何使用PHP索引对象来解决LeetCode算法问题,并提供一些相关的演示代码。 一、PHP索引对象介绍 PHP索引对...
    99+
    2023-09-01
    索引 对象 leetcode
  • MySQL全文索引如何解决like模糊匹配查询慢的问题
    这篇文章主要讲解了“MySQL全文索引如何解决like模糊匹配查询慢的问题”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“MySQL全文索引如何解决like模糊匹配查询慢的问题”吧!需求需要模...
    99+
    2023-07-04
  • 如何解决pycharm中用matplotlib画图不显示中文的问题
    前言: 其实很简单!举一个简单的例子! 这是一个简单的显示时刻的温度折线图: from matplotlib import pyplot as plt, font_manager i...
    99+
    2022-11-11
  • 如何解决MySQL启动时InnoDB引擎被禁用的问题
    这篇文章主要介绍如何解决MySQL启动时InnoDB引擎被禁用的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!发现问题今天在工作中,从本地数据库复制表数据到虚拟机 CentOS ...
    99+
    2022-10-18
  • 如何解决重置Mysql root用户账号密码的问题
    这篇文章主要介绍如何解决重置Mysql root用户账号密码的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题描述:使用mysqladmin.exe执行命令时出现以下错误提示:...
    99+
    2022-10-18
  • 如何解决页面整体使用transform scale后地图点位点击偏移错位问题
    如何解决页面整体使用transform scale后地图点位点击偏移错位问题,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。最近在可视化项目中使用 css3 trans...
    99+
    2023-06-26
  • 如何解决Adobe Reader因不再吸引Linux用户决定退出Linux系统的问题
    本篇内容主要讲解“如何解决Adobe Reader因不再吸引Linux用户决定退出Linux系统的问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决Adobe Reader因不再吸引Li...
    99+
    2023-06-13
  • 如何解决vue的图片需要用require的方式进行引入问题
    这篇文章主要介绍了如何解决vue的图片需要用require的方式进行引入问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。图片用require方式进行引入在vue中,我们有时...
    99+
    2023-06-29
  • 如何解决html-jquery/js引用外部图片时遇到看不了或出现403的问题
    这篇文章主要介绍如何解决html-jquery/js引用外部图片时遇到看不了或出现403的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!解决方法如下所示:<script&n...
    99+
    2022-10-19
  • 如何解决微信图片防盗链“此图片来自微信公众平台 未经允许不得引用”问题
    小编给大家分享一下如何解决微信图片防盗链“此图片来自微信公众平台 未经允许不得引用”问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作