Maxcompute造数据-方法详解

简介: 造一点模拟数据的方法

概述

造数据在一些奇怪的场合会被用到。一般我们是先有数据才有基于数据的应用场合,但是反过来如果应用拿到另外一个场景,没有数据功能是没有方法演示的。


一般较为真实的数据,脱敏后就可以应用在功能测试和演示的场合。但是数据脱敏其实也满复杂(脱敏过重数据就用不了了,过低数据又泄漏了),所以自己模拟一些数据,似乎更安全。


我个人一般遇到的造数据场景有两个。第一,是有合作伙伴或者同事咨询一个SQL处理数据的方法,没有数据。第二,就是有时候会有POC的一些场景,没有提供真实模拟数据,需要自己模拟。

分类

如果是单一的业务场景的数据模拟,很多时候单表就可以满足了。但是要是模拟某个业务场景,或者POC测试场景则要模拟一个业务系统中的相互关联的多张表。


造数据,一般会都会有些用户需求,会有明确的业务场景的描述。也会有一些其他要求,例如:表的记录数、行的存储、字段的生成规则、字段的值域、字段的枚举值,还可能会给少量真实的数据。


2.1. 一个表


单独造一张表的数据可能非常简单,比如我们日常测试一个函数,测试一段SQL的JOIN逻辑。也可能非常复杂,构造一个表,也就相当于构造一个业务系统。


2.2. 一个业务系统


业务系统相对于单表来说只是表的数量增加了。而且,因为业务系统的表间是存在主外键关系的,所以,需要先造代码表(维度表),然后再造业务表(事实表)。

方法

造模拟数据的方法分为两个阶段,第一阶段是构造一个小表,产生代码表(维度表),然后第二阶段利用笛卡尔积快速乘出需要的数据量。在这其中,列的数据值填充可以使用随机函数生成。

3.1. 构造一个常量小表


Maxcompute最简单的造数据的方法是insert into values语句,这一般也是我最常用的。在不支持这个语句之前的更早的版本,使用的是union all的方法。如果不想实际写入数据到,则可以使用from values 和 with 表达式。

示例1:通过insert … values操作向特定分区内插入数据。


命令示例如下:

--创建分区表srcp。
create table if not exists srcp (key string,value bigint) partitioned by (p string);--向分区表srcp添加分区。
alter table srcp add if not exists partition (p='abc');--向表srcp的指定分区abc中插入数据。
insert into table srcp partition (p='abc') values ('a',1),('b',2),('c',3);--查询表srcp。
select * from srcp where p='abc';--返回结果。
+------------+------------+------------+
| key        | value      | p          |
+------------+------------+------------+
| a          | 1          | abc        |
| b          | 2          | abc        |
| c          | 3          | abc        |
+------------+------------+------------+

示例2:通过values table操作插入数据。

命令示例如下:
--创建分区表srcp。
create table if not exists srcp (key string,value bigint) partitioned by (p string);--向表srcp中插入数据。
insert into table srcp partition (p) select concat(a,b), length(a)+length(b),'20170102' from values ('d',4),('e',5),('f',6) t(a,b);--查询表srcp。
select * from srcp where p='20170102';--返回结果。
+------------+------------+------------+
| key        | value      | p          |
+------------+------------+------------+
| d4         | 2          | 20170102   |
| e5         | 2          | 20170102   |
| f6         | 2          | 20170102   |
+------------+------------+------------+

values (…), (…) t(a, b)相当于定义了一个名为t,列为a和b,数据类型分别为STRING和BIGINT的表。列的类型需要从values列表中推导。


示例3:from values或者union all组合的方式,构造常量表。


命令示例如下:

with t as (select 1 c union all select 2 c) select * from t;
--等价于如下语句。
select * from values (1), (2) t(c);--返回结果。
+------------+
| c          |
+------------+
| 1          |
| 2          |
+------------+

以上例子来源于:
https://help.aliyun.com/document_detail/73778.html?spm=a2c4g.11186623.6.732.7e477b57ZhLOGj


3.2. 利用笛卡尔积构造大表


众所周知,笛卡尔积的写法只能用在MAPJOIN提示的情况下。所以,第一步构造出来的常量小表是可以使用MAPJOIN的。


命令示例如下:


-- 1 构造一个常量表(我这里用的有序数字,方便使用where去取制定数量的记录数去乘笛卡尔积)

create table za1 as 
select c0 from values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)
,(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30)
,(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),(41),(42),(43),(44),(45)
,(46),(47),(48),(49),(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),(60)
,(61),(62),(63)
t(c0);-- 2 使用常量表多次关联,构造出需要的记录数[大家使用计算器大概算一下N的多少次方够用]
create table zb1 as 
select *from(
-- 10*63*63=39690
select /*+mapjoin(t2,t3)*/1000000 + row_number() over(partition by 1)-1 as c0from za1 t1 -- 63join za1 t2 -- 63join(select c0 from za1 limit 10)t3 -- 10
)t
;--3 第2步构造的表已经达到万级,用这个表再构造的表记录数就可以轻松达到亿级

3.3. 利用随机值有序值填充列


数据种类从本质上可以分为2种,序列值和枚举值。序列值,就是有序的一个数列,使用row_number()函数来实现,在这个场景里主要定义为主键。枚举值就是少数的一些代码值(数值、金额、代码),分布在记录中,这些枚举值主要使用随机函数来填充。其他情况,目前个人还未遇到,就不描述了。


命令示例如下:

-- 1 有序值,在这个例子中,生成的数据是一个有序的从1000000-1036689的序列,可以作为业务主外键使用
select /*+mapjoin(t2,t3)*/1000000 + row_number() over(partition by 1)-1 as c0from za1 t1 -- 63join za1 t2 -- 63join(select c0 from za1 limit 10)t3 -- 10
;-- 2 随机值/固定值,在这个例子中c2列会生成一个相对均匀的1-1000的值
-- 随机函数生成的随机数是浮点值,必须要转为bigint
select /*+mapjoin(t2,t3)*/1000000 + row_number() over(partition by 1)-1 as c0,1617120000 as c1,cast(round(rand()*999,0) as bigint)+1 as c2from za1 t1 -- 63join za1 t2 -- 63join(select c0 from za1 limit 10)t3 -- 10
;

3.4. 不同的数据类型的构造


一般数据类型可以分为4种,主键唯一值、字符串代表的枚举值、数值、日期时间。刚才的例子里面构造的都是数值,唯一区别的是枚举值是数字而不是文本,而且没有构造日期时间。那么如果确实需要,该怎么实现。


时间可以构造成unixtime,就可以转化为数值。文本类型的枚举值,可以先构造代码表,再构建好业务表后再关联出来(一般业务系统存储的也是代码值,而不是一个长字符串)。
命令示例如下:

-- 利用代码表转文本
with za as (
select * from values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)
,(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30)
,(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),(41),(42),(43),(44),(45)
,(46),(47),(48),(49),(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),(60)
,(61),(62),(63)
t(c0)
)
,ta as (
select * from values ('zhangsan',4),('lisi',5),('wangmazi',6) t(a,b))
select k,a,b,cfrom(
select 100 + row_number() over(partition by 1)-1 as k,cast(round(rand()*3,0) as bigint)+3 as cfrom za  -- 63limit 3
)tb join ta on ta.b=tb.c
;
返回:
k   a   b   c
101 lisi    5   5
102 wangmazi    6   6
103 zhangsan    4   4-- 利用unixtimetamp转日期时间
with za as (
select * from values(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12),(13),(14),(15)
,(16),(17),(18),(19),(20),(21),(22),(23),(24),(25),(26),(27),(28),(29),(30)
,(31),(32),(33),(34),(35),(36),(37),(38),(39),(40),(41),(42),(43),(44),(45)
,(46),(47),(48),(49),(50),(51),(52),(53),(54),(55),(56),(57),(58),(59),(60)
,(61),(62),(63)
t(c0)
)
select k
,from_unixtime(1617120000) as t
,from_unixtime(1617120000
+3600000 * c )   -- 小时as b
,cfrom(
select 100 + row_number() over(partition by 1)-1 as k,cast(round(rand()*3,0) as bigint)+3 as cfrom za  -- 63limit 3
)tb 
;
返回:
k   t   b   c
100 2021-03-31 00:00:00 2021-03-31 03:00:00 3
101 2021-03-31 00:00:00 2021-03-31 05:00:00 5
102 2021-03-31 00:00:00 2021-03-31 06:00:00 6

实践

4.1. 实践案例


在前段时间经历的一个电信行业的POC项目,客户最开始给了80行真实数据,要求造十几亿左右的数据,并给了一些非常特殊的数据要求。


原始数据和根据客户要求处理过程处理完后的数据特征的要求


记录数:单表的记录数,原始16亿,处理后1.7亿;


用户数:1千4百万;


设备数:23万;


单行记录大小:原始数据行记录436KB,处理完后是157KB;


单用户记录数(最小、最多、中位):最小值是1;最大值原始未3万,处理后是2千4百;中位数原始值是51,处理后是4;


如下表:

时间类别记录数用户数用户记录数最小用户记录数最多用户记录数中位设备数单行(KB)
9:00原始16684860591429750013197351231272436
9:00处理17481769413371656124414230860157

根据上述要求,第一步是分析业务需求,原始数据有61列,但是真实参与数据计算的列只有10列。所以,构造原始表只需要把这10列构造出来,再把原始给的61列的记录的列选取1行关联上去即可。


分析原始数据结构,选区参与计算的数据列:

create table if not exists t_log10 (imei_tac             int      comment '用户设备ID1' 
,phone7               int      comment '用户设备ID2'  
,imsi                 string   comment '用户设备ID3'  
,msisdn               string   comment '用户设备ID4' 
,tac                  int      comment '电信设备ID1'
,cell_id              int      comment '电信设备ID2'
,Procedure_Type       int      comment '业务类型'
,Procedure_Start_Time bigint   comment '业务开始时间,unixtimestamp'
,Procedure_status     int      comment '业务状态,固定值1'
,country_code         int      comment '国家码,固定值-406'  )
partitioned by (hh string);

电信业务中,这个业务场景描述的是用户手机设备在电信运营商基站设备上注册的情况。这个业务计算使用的字段10个。有5个是用户设备维度相关,分别是用户设备ID(1-4)和国家码;有2个是电信设备维度相关,分别是电信设备ID(1-2)。还有3个是用户设备与电信设备业务发生相关的,分别是业务类型、业务状态、业务开始时间。


所以,在做了需求分析后,我认为我需要先构建一个用户设备维度表和电信基站设备维度表,再根据这些维度表构建电信业务事实表(业务表)。
第一步,构建电信基站维度(代码)表:

drop table if exists t_tac_lacid;
create table if not exists t_tac_lacid (id bigint,tac bigint,lacid bigint);insert overwrite table t_tac_lacid
select /*+mapjoin(t2)*/row_number() over(partition by 1)+100000 as rn
,t1.c0+6001  as tac
,t2.c0+1201  as lacid
from (select row_number() over(partition by 1)-1 as c0 from zb1 limit 2300)t1
join (select row_number() over(partition by 1)-1 as c0 from zb1 limit 100)t2
;
-- 230000

在这个例子,通过构建的zb1选区特定的记录数,通过笛卡尔积乘出指定的记录数的结果集。因为两个ID要构建出唯一主键,所以,这里使用了row_number窗口函数。在构建主键的时候,使用了100000+这种方式来构建固定长度的ID。
第二步,构建用户设备维度(代码)表。

drop table if exists t_user;
create table t_user (imei_tac bigint,phone7 bigint,imsi string ,msisdn string);insert overwrite table t_user
select rn as imei_tac
,cast(substr(to_char(rn),2,7) as bigint)+1000000 as phone7
,substr(MD5(rn), 1,10) as imsi
,substr(MD5(rn),11,10) as msisdn
from(
select /*+mapjoin(t2,t3,t4)*/row_number() over(partition by 1)+10000000 as rn
from za1 t1
join za1 t2
join za1 t3
join (select c0 from za1 limit 58) t4
-- limit 100
)t;
-- 14502726
-- 63*63*63*58 = 14502726

在这个例子,通过4次使用za1这个表构建了一个看起来很真实的记录数(实际上造数据差几条没区别,这里有点无聊)。使用row_number窗口函数构建了业务主键,并转化了几种形式(MD5截取)构建了不同的主键的样式。然后使用了随机函数构建了基站信息。这里面实际上把基站信息也做了计算,这些特殊处理主要是为了构建最后的结果表。


最后一步就是构建结果表了,因为前面我们还没有考虑中位数、极值和处理后结果的问题,所以,实际上最后的实现比较复杂(太长了,就不粘出来了,有需要单独找我要吧)。


满足特殊要求的方法是用户分段:


1) 极值,非常小的用户记录数满足用户极值[例如选500个用户


2) 中位数,中位数一定是超过了一半以上的用户的记录数


3) 补充数,除去极值与中位数剩下的用户


需要使用提示来改善性能,因为造数据的原始表都非常小,map阶段一般只有1个worker。所以,必须要把map阶段的数据块输入切小,把map和reduce的资源给大了。

set odps.sql.mapper.cpu=200;
set odps.sql.mapper.memory=8192;
set odps.sql.mapper.split.size=4;
set odps.sql.reducer.cpu=200;
set odps.sql.reducer.memory=8192;

4.2. 总结


造数据场景大部分时候都比较简单,但是,也会遇到上述这种特殊的复杂情况。但是复杂的业务主要还是考验数据加工的能力,怎么使用基础表生成复杂表,还是关系数据库的关系模型的构建的过程。


单个数据表的构建,首先需要先分析出业务中的维度和事实的部分,再构建维度,利用维度构建事实。

原文链接

本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/513169.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python计算运动会某个参赛选手的得分。数据保存在文件中_成绩计算电脑程序的使用说明...

成绩计算电脑程序的使用说明为了计算成绩,特制作这个电脑程序,说明如下:一、开发软件:Python二、使用说明:在电脑D盘根目录下建立两个excel文件,一个是1.xlsx,另一个是2.xlsx其中,1.…

android 创建文件夹_Android 动画小记

精简介绍Android中的动画,主要介绍用法。动画种类包括了:补间动画、逐帧动画、属性动画,前两者统称为视图动画。补间动画包括了平移、旋转、缩放和透明度四种,每种动画支持xml和代码设置。另外还有一种组合动画,就是将…

命题公式的主合取范式C语言,命题公式主范式的自动生成与形式输出.pdf

收稿日期 2006 04 19 作者简介 张会凌 1954 男 甘肃成县人 甘肃联合大学数学与信息学院副教授 主要从事微分几何与计算机方面 的研究 文章编号 1672 691X 2006 05 0049 04 命题公式主范式的自动生成与形式输出 张会凌 甘肃联合大学 数学与信息学院 甘肃 兰州 730000 摘 要 在文…

2021金蝶全球创见者大会成功举办, 500强企业共话EBC数字战斗力

11月27日,由金蝶主办的“2021全球创见者大会”成功举办。大会以“用数字战斗力,向管理要效益”为主题,求索不确定时代,EBC如何帮助500强及中小企业拥抱数字战斗力,构建企业韧性。 据了解,金蝶全球创见者大…

使用管控策略,设定多账号组织全局访问边界

简介: 企业上云多账号架构中,如何做到从上到下管理的同时,处理好员工的权限边界问题? 由多账号上云模式说起 多账号上云模式的产生 我们的企业客户上云,一般都是从尝试部署少量业务开始,然后逐步将更多业…

使用MaxCompute LOAD命令批量导入OSS数据最佳实践—STS方式LOAD开启KMS加密OSS数据

简介: MaxCompute使用load overwrite或load into命令将外部存储的数据(如:oss)导入到MaxCompute前的授权操作。 MaxCompute使用load overwrite或load into命令将外部存储的数据(如:oss)导入到M…

mamcache登录、_gomemcache首页、文档和下载 - memcache客户端库 - Go语言中文网 - Golang中文社区...

**安装**使用 go get$ go get github.com/bradfitz/gomemcache/memcache此命令后gomemcache即可使用。它的来源将是:$GOPATH/src/github.com/bradfitz/gomemcache/memcache**示例**import ("github.com/bradfitz/gomemcache/memcache")func main() {mc : …

pca降维的基本思想_R语言进行PCA分析

点击上方「蓝字」关注我写在前面前面我们知道了降维分析学习了PCoA分析今天学习PCA分析...PCA(Principal Component Analysis),即主成分分析方法,是一种使用最广泛的数据降维算法。PCA的主要思想是将n维特征映射到k维上,这k维是全新的正交特征…

c语言线性分类回归库 台湾,最全的线性回归算法库总结—— scikit-learn篇

原标题:最全的线性回归算法库总结—— scikit-learn篇本文建议收藏后食用更加美味scikit-learn对于线性回归提供了比较多的类库,这些类库都可以用来做线性回归分析,本文就对这些类库的使用做一个总结,重点讲述这些线性回归算法库的…

吉麦新能源与联想签订战略合作协议,共同拥抱智能网联汽车升维时代

11月25日,吉麦新能源汽车与联想战略合作签约仪式成功举行,双方正式建立战略合作伙伴关系。未来,双方将在车联网、云解决方案及服务、IT基础架构产品服务、智慧工厂服务领域开展深入合作,合力推动新能源造车数智化转型,…

供应链商品域DDD实践

简介: DDD是一套方法论,实践能否成功,不仅仅是个技术问题,更是执行贯彻实施的问题。本文将就DDD的基本概念和DDD的实施进行分享。 作者 | 侧帽 来源 | 阿里技术公众号 前言 供应链商品域DDD实践时间不长,在实践过程也…

wps编号无法继续_wps怎么自动编号【解决步骤】

我们在使用电脑工作的过程中时常会遇到各种奇奇怪怪的问题,比如最近就有不少用户来问小编关于wps怎么自动编号的问题,于是小编就在网上查了一下wps怎么自动编号的解决方法,其实wps怎么自动编号操作起来很容易只需要1:打开一个wps文…

c语言EOF0x99,C语言选择题99道.doc

C语言选择题99道1.有以下程序int f1(int x,int y){ return x>y?x:y; }int f2(int x,int y){ return x>y?y:x; }main(){int a4,b3,c5,d,e,f; df1(a,b); df1(d,c); ef2(a,b); ef2(e,c); fabc-d-e; printf("%d,%d,%d\n",d,f,e);}执行后输出的结果是______。 A&a…

20岁,Universal GIS拥抱新生的GIS信创

近20年来,在快速发展的IT新技术和国家应用需求的双轮驱动下,我国GIS技术和产业得到了飞速发展,GIS软件应用范围从几个行业深入到了数字中国建设中的数字经济、数字政务、数字社会、数字生态建设的几乎所有行业和领域。GIS软件已成为国家治理体…

php与python缺点_php和python的比较

hon 的应用现在越来越多了,想多了解点 pygtk 和 django 的东西,但只 有一些 php 和 C 的基础, 而 python 的语法还是比较独特的。 接触 python 半年多,总结一点和 php 的比较以及优缺点。 首先, python 的性能一直比较…

如何用Netty写一个高性能的分布式服务框架?

byte[] -->堆外内存 / 堆外内存--> byte[] -->java对象。 优化:省去 byte[] 环节,直接 读/写 堆外内存,这需要扩展对应的序列化框架。 String 编码/解码优化。 Varint 优化:多次 writeByte 合并为 writeShort/writeInt/w…

css x轴不滚动_css – 固定div,动态内容不滚动

我有一个固定的div与动态加载的li元素.现在我希望div-content在有超过9个li元素和滚动条时滚动:这就是它的样子:此时固定div继续在页脚上,内容无法滚动.这是所有div的css:#fixed-div {position: fixed;width: 30%;margin-top:290px;padding-t…

C语言rec文件如何打开,REC 文件扩展名: 它是什么以及如何打开它?

REC 疑难解答典型的 REC 开放挑战Squared 5 MPEG Streamclip 不在你尝试加载 REC 文件并收到错误,例如 “%%os%% 无法打开 REC 文件扩展名”。 通常,这是因为你没有安装适用于 %%os%% 的 Squared 5 MPEG Streamclip。 操作系统不知道如何处理你的 REC 文…

Quick BI:降低使用门槛,大东鞋业8000家门店的数据导航

简介: 通过引入MaxCompute和Quick BI,大东解决了以往数据查询即刻导致数据库闪崩的状况,还搭建起完善的报表体系,稳定应对高频、高并发的数据分析。 大东鞋业一季大约有500款的新品。大区下辖的各个分公司要对这500款新品进行订货…

绿盟科技发布安全知识图谱技术白皮书

随着全球数字化和万物互联的加速发展,近年来勒索病毒的攻击手段不断升级,例如今年美国最大燃油管道受攻击导致美国17个州和华盛顿特区进入紧急状态,引起全球关注。当下企业如何提高安全运营知识以面对不断升级的威胁攻击? 近日&a…