基本的なビッグデータスキルのための初心者ガイド




この記事では、データ作業におけるデータ基盤と複雑なデータ クエリの 2 つの基本スキルを紹介します。


背景


現在、ビジネス アップグレードの反復プロジェクトであっても、エクスペリエンス最適化プロジェクトであっても、データの需要が増加しています。データ要件は主に次の側面に焦点を当てています。

  1. プロジェクト データ ダッシュボードの構築: 特に一部の AB 実験ダッシュボードでは、プロジェクトのコア データの変更を視覚的に表示できます。

  2. データ分析: プロジェクト開始前の探査とマイニング、およびプロジェクト後の効果分析
    しかし、現在、共通の矛盾、つまり、
    増大するデータ需要と遅れているデータ生産性との間の矛盾が存在します。


ことわざにあるように、自分自身を求めるよりも、他の人に求める方が良いです。技術系の学生 (特に開発職の学生) にとって、基本的なデータ スキルを習得することは難しくありませんが、適切な入門ガイドがありません。この記事は、データ処理を学びたい学生がすぐに始められるように設計されています。


基本的なスキル

▐データ  基盤

このパートでは、まず MaxCompute (旧称 odps) プラットフォームでのデータ処理開発の基本知識を紹介します。

  • テーブルベース


テーブルはデータ処理の開始点と終了点であるため、他の人のテーブルを理解し、独自のテーブルを作成できることは、データ処理スキルの最も基本的な部分です。

テーブルの作成と変更

一時テーブルを作成します。
-- 临时表命名建议以“tmp_”开头,odps会知道该表是临时表-- 临时表的生命周期建议按需设置,不要设置太长,避免资源浪费CREATE TABLE tmp_ut_cart_clk LIFECYCLE 7 AS SELECT  user_idFROM    <用户浏览数据表>


正式なテーブルを作成します。

-- analytics_dw是odps的空间名,后面的是表名-- 空间名.表名 才能确定唯一的数据表-- 以下是一个实际案例CREATE TABLE IF NOT EXISTS analytics_dw.ads_tb_biz_request_opt_1d(    bucket_id                       STRING COMMENT '分桶'    ,os                             STRING COMMENT '系统'    ,uv                             BIGINT COMMENT '分桶用户数'    ,pv                             BIGINT COMMENT '页面访问pv'    ,page_stay_time                 BIGINT COMMRNT '页面停留时间(ms)'    ...)PARTITIONED BY       -- 分区(    ds                              STRING COMMENT '日期')LIFECYCLE 30;

PARTITIONED BY はパーティション化フィールドを指定することに注意してください。 ODPS データ処理ではパーティショニングが非常に重要です。パーティションを適切に選択すると、データ クエリが大幅に高速化されます。

パーティションを簡単に理解するとファイル ディレクトリの概念であり、ディレクトリ情報が正確であればあるほど、クエリに必要な元のデータが少なくなり、クエリ効率も自然に高くなります。


テーブルの命名

定期的に更新して他の人が使用する必要があるテーブルを作成する場合、テーブルの名前は特定の基準に準拠する必要があります。簡単にまとめると、日常のデータ処理で頻繁に使用されるテーブルには、次の 4 種類があります。
タイプ
命名プレフィックス
説明する
寸法表
dim_xxxx
通常、情報の一部を補足するために他のテーブルを関連付けることによって、いくつかのディメンション情報を提供します。
リスト
dwd_xxxx
クリーンアップ、フィルタリング、およびフィールド処理が行われたテーブル。それは客観的な行動の説明にすぎません。データ処理と分析の基礎です
ライト概要表
dws_xxxx
その後のデータ分析を目的として、いくつかのディメンションが集計および計算されます。率直に言うと、これは dwd のいくつかの次元を集計してグループ化することを意味します。テーブルを緩やかに集計すると、それほど重要ではない情報が失われるため、その後の分析が容易になります。
アプリケーション層テーブル
ads_xxxx
上位層アプリケーションにデータを提供するテーブル。このレベルでは、テーブル内のデータは基本的に処理を継続する能力がありません。これらのテーブルのデータは通常、レポートを構成したり、意思決定を支援したりするために使用されます。

開発者にとって、自分でテーブルを作成する必要がある場合、通常は広告タイプのテーブルになります。テーブルには次の形式で名前を付けることができます。
<スペース名>.ads_ <事業> <副業/あれば> <機能/実験> <データ統計期間/1日/7日/30日など>

  • 基本的なクエリ


基本的なクエリはデータ処理の基礎です。このステップの主な作業には、データのクリーニングとフィルタリング、フィールドの処理と拡張が含まれ、後続のデータ処理のための強固な基盤を築きます。

以下は非常に基本的なクエリ SQL です。
SET odps.sql.mapper.split.size=2048; -- 默认是256(单位M)

SELECT user_id ,page ,time_stamp ...FROM <App用户使用明细表>WHERE ds = '${bizdate}'AND product = '<App名称>'AND event_type = '<事件类型:浏览\点击>'AND page = '<页面标识>';

クエリされるデータの量が膨大な場合、クエリ中に次のエラーが発生する可能性があります。
失敗: ODPS-0130071:[0,0] セマンティック分析例外 - 物理プランの生成に失敗しました: java.lang.RuntimeException: com.aliyun.odps.lot.cbo.plan.splitting.disruptor.InstExceedLimitException: task:M1 インスタンス数が超過しました限界99999

これは、ODPS がデータ ストレージ サイズ/splitSize に基づいて必要なインスタンス数を決定するためですが、99999 の上限があり、制限を超えるとエラーが報告されます。このとき、splitSizeを適当に大きくするだけです(毎回*2ずつ調整できます)。

文字列処理

クエリ中の一般的な文字列処理方法:
        -- 单个条件SELECT  IF(page = 'Page_XXX', 'y', 'n') AS is_page_xxx 
-- 多个条件 ,CASE WHEN hh <= 12 THEN '上午' WHEN hh > 12 AND hh <= 18 THEN '下午' ELSE '晚上' END AS 时间段
-- 超级有用:提取args中的kv ,KEYVALUE(args, ',', '=', 'itemid') AS item_id
-- 分割字符串(value为“a_b_c”这种有规律的字符串可以使用) ,SPLIT(value, '_') AS value_list -- 这个是数组,可以使用索引 value_list[0]
-- 去除空值(使用a,b,c中第一个不为NULL的值,否则用最后的空字符串) ,COALESCE(a, b, c, '') AS xxx
-- 版本比较,超级实用 ,IF(bi_udf:bi_yt_compare_version(app_version, '10.24.10') >= 0, 'y', 'n') AS is_target_version

-- 解析JSON,提取目标信息 ,GET_JSON_OBJECT(json_str, '$.section.item.name') AS item_name
-- 类型转换 ,CAST(user_id AS BIGINT) AS user_id
-- 大小写转换 ,TOUPPER(os) , TOLOWER(os)

日付処理

日付と時刻の処理は、「過去 7 日間のデータをクエリする」などの文字列処理でも一般的です。日付に対して一般的に使用される関数は次のとおりです。
-- 日期格式描述  yyyy    年,4位  MM      月,2位  dd    日,2位  hh/HH    12小时制/24小时制,2位  mi    分钟,2位  ss    秒,2位  SSS    毫秒,3位-- 通过上面这些格式就能在转化具体的日期时描述日期的格式:20230807             yyyyMMdd2023-08-07          yyyy-MM-dd20230806 13:22:00            yyyyMMdd HH:mi:si

-- 单纯查询某个日期之前或者之后的数据ds >= '20230807'

TO_DATE('20230807', 'yyyyMMdd') -- 将日期字符串转为 datetime 实例,日期处理的基础
TO_CHAR(datetime, 'yyyyMMdd') -- 将日期函数处理得到各种datetime转换为字符串
FROM_UNIXTIME(123456789) -- 将unix时间戳转换成datetime对象
-- 日期加减,自动处理进位关系DATEADD(TO_DATE('20230807', 'yyyyMMdd'), 7, 'dd') -- 20230814DATEADD(TO_DATE('20230807', 'yyyyMMdd'), -7, 'dd') -- 20230731
-- 2个日期间隔(第一个日期-第二个日期,结果可为负)DATEDIFF(TO_DATE('20230807', 'yyyyMMdd'), TO_DATE('20230806', 'yyyyMMdd'), 'dd') -- 1
-- 提取指定时间-- 在希望分小时段统计的场景下很实用DATEPART(TO_DATE('2023-08-07 12:13:22', 'yyyy-MM-dd hh:mi:ss'), 'hh') -- 12


  • 関連クエリ


多くの場合、1 つのテーブル内のデータではニーズを満たせないため、他のテーブルを通じて情報を補完する必要があり、この場合はデータを関連付ける必要があります。SQL では結合操作として表示されます。

一般的に使用される関連付け操作には、LEFT JOIN、RIGHT JOIN、および INNER JOIN が含まれます。
-- 基本的join语法如下SELECT  a.user_id         ,a.arg1        ,a.args        ,b.bucket_idFROM    (    SELECT  user_id          ,arg1          ,args   FROM  <用户手淘行为表>) aLEFT JOIN (    SELECT  user_d            ,bucket_id   FROM  <AB实验分流表>) bON    a.user_id = b.user_id;
-- left joinright join、inner join差别
left join:会保留左表的所有数据(在上面这个例子中左表就是 a,join左边的表),右表中没有匹配的数据将会丢失right join:和left join相反会保留右表(b)的所有数据,左表中没有匹配的数据会丢失inner join:最终只有两个表的交集部分会被保留下来

結合操作ではエラーが発生しやすく、誤ったクエリ結果が得られますが、そのようなエラーは非常に微妙で検出が難しい場合があります。主な理由は、一致条件が省略されているか、関連するフィールドに重複した値が含まれているため、多対多の状況が発生し、データの拡大につながり、統計結果に影響を与えることです。問題を回避するには、次のような提案があります。
  1. 必要なデータのクリーニングと重複排除は、最初にテーブル a と b を関連付けてから処理するのではなく、テーブル a と b を関連付ける前に実行する必要があります。
  2. テーブル a と b が両方とも大量のデータを含むテーブルである場合は、少量のデータ サンプルをランダムに選択して一時テーブル a' および b' を生成し、最終的なテーブルのデータ サイズとデータ サイズを比較することをお勧めします。 a' と b' を比較して、期待どおりかどうかを確認します。

特に、小さなテーブルと大きなテーブルを関連付ける場合、MapJoin を使用することで効率が向上します。たとえば、日次取引テーブルに商品カテゴリ情報がある場合、対応する業界情報との関連付けが必要になります。カテゴリと業界間のマッピング 関係が小さなテーブルの場合、MapJoin を使用してタスクの実行効率を向上させることができます。

   
   
   
   
   
SELECT /* + mapjoin(J2) */ J1.* ,J2.industry FROM <订单表> J1 LEFT JOIN ( SELECT cate_level1_id ,industry FROM <行业维表> WHERE ds = '${bizdate}' ) J2 ON J1.cate_level1_id = J2.cate_level1_id ;

  • 集計クエリ


集計とは、データ内の特定のディメンション (システム、バージョンなど) に対して一連の計算を実行して、単一の値を返すことです。一般的にはGroup By操作としてSQLに反映されます。一般に、データ処理 (インジケーターの計算) の最後の数ステップは、集計操作から切り離すことができません。

   
   
   
   
   
-- 常见聚合函数 AVG(age) AS avg_age ) -- 平均值
SUM(cnt) AS total_cnt -- 求和
MIN(age) AS min_age -- 最小值
MAX(age) AS max_age -- 最大值
COUNT(*) / COUNT(item_id) -- 计数 count(*)不会忽略null,count(xx)会忽略null
COUNT(DISTINCT utdid) -- 去重计数
COLLECT_SET(item_id) -- 将去重后的item_id存在一个数组中
COLLECT_ARRAY(item_id) -- 将item_id存在一个数组中(不去重)
PERCENTILE(duration, 0.95) -- 求分位数


通常、集計を実行するときは、毎日のトランザクションで各州の GMV をクエリしたい場合や、すべての州の全体的な GMV をクエリしたい場合など、特別なニーズが発生することがあります。通常、次のように記述する必要があります。

SELECT  province      ,SUM(amount) AS gmvFROM  <每日成交表>GROUP BY province
UNION ALL
SELECT '整体' AS province ,SUM(amount) AS gmvFROM <每日成交表>

ディメンションが少ない場合はこのように書いても大丈夫ですが、この要件を考慮すると、各州の各都市の GMV も見たいし、州全体の GMV も見たいし、全州の流通総額 この時点で上記の書き方をすると非常に面倒になります。現時点では、CUBE または GROUPING SETS を使用してクエリ ロジックを簡素化することを検討できます。
SELECT  IF(GROUPING(province) == 0, province, 'all') AS province        ,IF(GROUPING(city) == 0, city, 'all') AS city        ,SUM(amount) AS gmvFROM  <每日成交表>GROUP BY GROUPING SETS((), (province), (province, city))
-- 下面是CUBE的示例
SELECT IF(GROUPING(province) == 0, province, 'all') AS province ,IF(GROUPING(city) == 0, city, 'all') AS city ,SUM(amount) AS gmvFROM <每日成交表>GROUP BY CUBE(province, city)
-- 说明:-- GROUPING SETS:按照制定维度组合来做聚合-- CUBE:按照相关维度的全排列来做聚合
最後に、 データをクエリするときは、  パーティションを指定する必要があります。パーティションを指定する必要があります。パーティションを指定する必要があります。

▐複雑な   データクエリ

実際、多くの学生は SQL の基本的な知識を持っていますが、データ クエリが少し複雑になると、少し無力になります。複雑な SQL は本質的に非常に読みやすく、保守しやすいため、これは正常です。開発アイデアと同様に、この問題を解決する方法は、複雑なロジックを単純なプロセスに分解し、クエリ ドールの数を減らすことです。個人的にオススメの方法 主な方法としては、一時テーブル、odps スクリプト、cte 式の 3 つがあります。

  • 一時テーブル (一時クエリに使用)


複雑なクエリ プロセスが分割され、クエリ ロジック全体が最終的に完了するまで、各プロセスのクエリ結果が一時テーブルとして保存されます。この方法は、データ分析を行う場合に特に役立ちます。

通常、データは数日で分析されます。これは次のテンプレートに従って実行できます。
-- 步骤1 甚至可以写注释方面以后理解-- 建议将关心的原始数据先清洗处理保存为临时表,方便后面做各种分析使用,提升效率DROP TABLE IF EXISTS tmp_step1_${bizdate};CREATE TABLE tmp_step1_${bizdate} LIFECYCLE 3 AS  -- 临时表生命周期不要设置太久,避免无意义的资源浪费SELECT  a        ,b        ,cFROM  <数据表1>WHERE  <筛选条件>;
-- 步骤2DROP TABLE IF EXISTS tmp_step2_${bizdate};CREATE TABLE tmp_step2_${bizdate} LIFECYCLE 3 AS SELECT a ,b ,cFROM tmp_step1_${bizdate} ;
-- ....
-- 关注的结果SELECT *FROM tmp_stepN_${bizdate}GROUP BY xxx;

例証します:

  1. 一時テーブル クエリは、ワンクリックで実行でき、何も考えずに最終結果が得られるように作成するのが最適で、これにより時間を大幅に節約できます。

  2. ${xxx} odps パラメータの記述方法では、SQL を実行する前に対応するパラメータの値を設定し、SQL 全体で対応するパラメータを置き換えることができます。本質は文字列置換です。1 つの SQL 内に複数のパラメータを出現させることができます。
  3. SQLを繰り返し実行できるようにするには、テーブルを作成する前に、対応するテーブルが作成されていないことを確認する必要があります(DROP TABLE)。


  • ODPS SCRIPT (制限があるため推奨されません)


この方法は、cte 発現後はお勧めできません。簡単な例は次のとおりです。
@step1 :=SELECT   XX FROM   XXXX;
@step2 :=SELECT YY FROM @step1;....
SELECT *FROM @stepN;

  • CTE 式 (強く推奨。使用したことのある人は全員、これが良いと言っています)


CTE を使用すると、複雑なタスクを分解し、SQL の可読性と保守性を向上させることができます。さらに、CTE は一時的なクエリに使用できるだけでなく、タスクを定期的なタスクとして発行することもできます。日々のデータ処理では次のテンプレートを使用できます。
WITHstep1 AS(  SELECT  XX  FROM    XXXX),
step2 AS ( SELECT YY FROM step1),
....
stepN AS ( SELECT ...) -- 最后的这括号后面不要加 ,
INSERT OVERWRITE TABLE <存储表名> PARTITION (ds = '${bizdate}') -- 一个WITH只支持一个INSERTSELECT *FROM stepN

最後に書きます


数据处理并不是神秘、难以掌握的技能。每个技术同学、产品同学都是可以学会基本的数据处理技能的。希望本文能帮助有需要的同学叩开数据处理的大门。

团队介绍


我们是大淘宝技术「基础交易终端团队」,主要负责电商核心交易链路业务和平台的研发,包含:淘宝购物车、下单、订单、物流、逆向等电商核心基础能力及创新型业务。这里有世界一流的技术产品,有丰富的业务场景,服务于十亿级的消费者,这里有巨大的挑战等你来。作为阿里的一支明星团队,负责阿里电商平台的核心交易主链路,是 阿里移动技术的基石,每年双十一核心链路保障。

现招聘移动端(Android/iOS)开发工程师,有前端开发经验者优先,有意者可以投递简历到:[email protected]


本文分享自微信公众号 - 大淘宝技术(AlibabaMTT)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

开源框架 NanUI 作者转行卖钢材,项目暂停开发 苹果 App Store 免费榜第一是黄色软件 TypeScript 刚刚流行起来,为什么大牛们就开始抛弃了? TIOBE 10 月榜单:Java 跌幅最大,C# 逼近 Java Rust 1.73.0 发布 男子受 AI 女友怂恿刺杀英国女王,被判入狱九年 Qt 6.6 正式发布 路透社:RISC-V 技术成为中美科技战的新战场 RISC-V:不受任何单一公司或国家的控制 联想计划推出 Android PC
{{o.name}}
{{m.name}}

おすすめ

転載: my.oschina.net/u/4662964/blog/10117419