操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    倫 大淘寶技術 2024年07月08日 18:03 浙江




    本文旨在收集整理ODPS開發(fā)中入門及進階級知識,盡可能涵蓋大多ODPS開發(fā)問題,成為一本mini百科全書,后續(xù)也會持續(xù)更新。希望通過筆者的梳理和理解,幫助剛接觸ODPS開發(fā)的同學快速上手。

    本文為該系列第一篇:入門篇。

    筆者不才,有任何錯誤紕漏,歡迎大家指正。


    基礎功能介紹


    ?功能分類


    一般來說,數(shù)據(jù)開發(fā)包括了以下幾個類型:


    ?MaxCompute功能


    在此,我們重點介紹一下其中MaxCompute模塊(MaxCompute是適用于數(shù)據(jù)分析場景的企業(yè)級SaaS模式云數(shù)據(jù)倉庫)的功能:



    基礎SQL


    ?DDL


    具體語句1:

    --創(chuàng)建新表。
     create [external] table [if not exists] <table_name>
     [primary key (<pk_col_name>, <pk_col_name2>),(<col_name> <data_type> 
                                                   [not null] [default <default_value>] [comment <col_comment>], ...)]
     [comment <table_comment>]
     [partitioned by (<col_name> <data_type> [comment <col_comment>], ...)]
    
    
    --用于創(chuàng)建聚簇表時設置表的Shuffle和Sort屬性。
     [clustered by | range clustered by (<col_name> [, <col_name>, ...]) 
      [sorted by (<col_name> [asc | desc] [, <col_name> [asc | desc] ...])] into <number_of_buckets> buckets] 
    --僅限外部表。
     [stored by StorageHandler] 
     --僅限外部表。
     [with serdeproperties (options)] 
     --僅限外部表。
     [location <osslocation>] 
    --指定表為Transactional1.0表,后續(xù)可以對該表執(zhí)行更新或刪除表數(shù)據(jù)操作,但是Transactional表有部分使用限制,請根據(jù)需求創(chuàng)建。
     [tblproperties("transactional"="true")]
    --指定表為Transactional2.0表,后續(xù)可以做upsert,增量查詢,time-travel等操作
     [tblproperties ("transactional"="true" [, "write.bucket.num"="N", "acid.data.retain.hours"="hours"...])] [lifecycle <days>]
    ;
    
    
    -------------------------------------------------------------------
    --例子:
    CREATE TABLE IF NOT EXISTS xxx.xxxx_xxxx_xxxx_hh
    (
      xxxxx             STRING COMMENT '商品'
      ,xxxxx           STRING COMMENT '名字'
    )
    COMMENT 'xxx表'
    PARTITIONED BY 
    (
      ds                  STRING COMMENT 'yyyymmddhh'
    )
    LIFECYCLE 7
    ;


    參數(shù)說明:

    external:可選。表示創(chuàng)建的表為外部表。

    if not exists:可選。如果不指定if not exists選項而存在同名表,會報錯。

    table_name:必填。表名。

    primary key(pk):可選。表的主鍵。

    col_name:可選,表的列名。

    col_comment:可選。列的注釋內(nèi)容。

    data_type:可選。列的數(shù)據(jù)類型。

    not null:可選。禁止該列的值為NULL。default_value:可選。指定列的默認值。

    table_comment:可選。表注釋內(nèi)容。

    lifecycle:可選。表的生命周期。

    partitioned by (<col_name> <data_type> [comment <col_comment>], ...:可選。指定分區(qū)表的分區(qū)字段。


    具體語句2:修改表的所有人

    alter table <table_name> changeowner to <new_owner>;
    
    
    --------------------------------------------------------
    --例子
    --將表test1的所有人修改為ALIYUN$xxx@aliyun.com
    alter table test1 changeowner to 'ALIYUN$xxx@aliyun.com';
    
    
    --將表test1的所有人修改為名稱為ram_test的RAM用戶
    alter table test1 changeowner to 'RAM$13xxxxxxxxxxx:ram_test';


    參數(shù)說明:

    table_name:必填。待修改Owner的表名。

    new_owner:必填。修改后的Owner賬號。如果要修改Owner為RAM用戶,格式為:RAM$<UID>:<ram_name>,其中UID為阿里云賬號的賬號ID,ram_name為RAM用戶顯示名稱。


    具體語句3:修改表的注釋

    alter table <table_name> set comment '<new_comment>';
    --------------------------------------------------------
    --例子
    alter table sale_detail set comment 'new coments for table sale_detail';


    參數(shù)說明:

    table_name:必填。待修改注釋的表的名稱。

    new_comment:必填。修改后的注釋名稱。


    具體語句4:修改表的修改時間

    alter table <table_name> touch;
    --------------------------------------------------------
    --例子
    alter table sale_detail touch;


    參數(shù)說明:

    table_name:必填。待修改表的修改時間的表名稱。


    具體語句5:重命名表

    alter table <table_name> rename to <new_table_name>;
    --------------------------------------------------------
    --例子
    alter table sale_detail rename to sale_detail_rename;


    參數(shù)說明:

    table_name:必填。待修改名稱的表。

    new_table_name:必填。修改后的表名稱。如果已存在與new_table_name同名的表,會返回報錯。


    具體語句6:刪除表

    drop table [if exists] <table_name>;
    --------------------------------------------------------
    --例子
    drop table if exists sale_detail;


    參數(shù)說明:

    if exists:可選。如果不指定if exists且表不存在,則返回異常。如果指定if exists,無論表是否存在,均返回成功。

    table_name:必填。待刪除的表名。


    具體語句7:查看表或視圖信息

    --查看表或視圖信息。
    desc <table_name|view_name> [partition (<pt_spec>)]; 
    --查看外部表、聚簇表或Transactional表信息。也可以查看內(nèi)部表的擴展信息。
    desc extended <table_name>;
    --------------------------------------------------------
    --例子
    desc test1;


    參數(shù)說明:

    table_name:必填。待查看表的名稱。

    view_name:必填。待查看視圖的名稱。

    pt_spec:可選。待查看分區(qū)表的指定分區(qū)。

    extended:如果表為外部表、聚簇表或Transactional表,需要包含此參數(shù)。


    具體語句8:查看分區(qū)信息

    desc <table_name> partition (<pt_spec>);
    --------------------------------------------------------
    --例子
    --查詢分區(qū)表sale_detail的分區(qū)信息。
    desc sale_detail partition (xxxx_date='201310',region='beijing');


    參數(shù)說明:

    table_name:必填。待查看分區(qū)信息的分區(qū)表名稱。

    pt_spec:必填。待查看的分區(qū)信息。


    具體語句9:查看建表語句

    show create table <table_name>;
    --------------------------------------------------------
    --例子
    --查看表sale_detail的建表語句。
    show create table sale_detail;


    參數(shù)說明:

    table_name:必填。待查看建表語句的表的名稱。


    具體語句10:列出所有分區(qū)

    show partitions <table_name>;
    --------------------------------------------------------
    --例子
    --列出sale_detail中的所有分區(qū)。
    show partitions sale_detail;


    參數(shù)說明:

    table_name:必填。待查看分區(qū)信息的分區(qū)表名稱。


    具體語句11:清空列數(shù)據(jù)

    ALTER TABLE <table_name> 
               [partition ( <pt_spec>[, <pt_spec>....] )] 
               CLEAR COLUMN column1[, column2, column3, ...]
                                   [without touch];


    參數(shù)說明:

    table_name:將要執(zhí)行清空列數(shù)據(jù)的表名稱。

    column1 , column2...:將要被清空數(shù)據(jù)的列名稱。

    partition:指定分區(qū)。

    pt_spec:分區(qū)描述。

    without touch:表示不更新LastDataModifiedTime。


    具體語句12:復制表

    clone table <[<src_project_name>.]<src_table_name>> [partition(<pt_spec>), ...]
     to <[<dest_project_name>.]<dest_table_name>> [if exists [overwrite | ignore]] ;
    
    
    ----------------------------------------------------------------------------
    --例子
     --復制表數(shù)據(jù)。
    clone table xxxx_detail partition (xxxx_date='2013', region='china') to xxxx_detail_clone if exists overwrite;


    參數(shù)說明:

    src_project_name:可選。源表所屬MaxCompute項目名稱。

    src_table_name:必填。源表名稱。

    pt_spec:可選。源表的分區(qū)信息。

    dest_project_name:可選。

    dest_table_name:必填。目標表名稱。


    ?DML


    具體語句1:插入或覆寫數(shù)據(jù)

    --插入:直接向表或靜態(tài)分區(qū)中插入數(shù)據(jù),可以在insert語句中直接指定分區(qū)值,將數(shù)據(jù)插入指定的分區(qū)。如果您需要插入少量測試數(shù)據(jù),可以配合VALUES使用。
    --覆寫:先清空表或靜態(tài)分區(qū)中的原有數(shù)據(jù),再向表或靜態(tài)分區(qū)中插入數(shù)據(jù)。
    
    
    insert {into|overwrite} table <table_name> [partition (<pt_spec>)] [(<col_name> [,<col_name> ...)]]
    <select_statement>
    from <from_statement>
    [zorder by <zcol_name> [, <zcol_name> ...]];
    
    
    
    
    ----------------------------------------------------------------------------
    --例子
    --向源表追加數(shù)據(jù)。其中:insert into table table_name可以簡寫為insert into table_name,但insert overwrite table table_name不可以省略table關鍵字。
    insert into xxxx_detail partition (xxxx_date='2013', region='china') values ('s1','c1',100.1),('s2','c2',100.2),('s3','c3',100.3);
    
    
    --執(zhí)行insert overwrite命令向表xxxx_detail_insert中覆寫數(shù)據(jù),調(diào)整select子句中列的順序。
    insert overwrite table xxxx_detail_insert partition (xxxx_date='2013', region='china')
        select xxxx_id, xxxx_name, xxxx_price from xxxx_detail;


    參數(shù)說明:

    table_name:必填。需要插入數(shù)據(jù)的目標表名稱。

    pt_spec:可選。需要插入數(shù)據(jù)的分區(qū)信息。

    col_name:可選。需要插入數(shù)據(jù)的目標表的列名稱。

    select_statement:必填。select子句,從源表中查詢需要插入目標表的數(shù)據(jù)。

    from_statement:必填。from子句,表示數(shù)據(jù)來源。

    zorder by <zcol_name> [, <zcol_name> ...]:可選。向表或分區(qū)寫入數(shù)據(jù)時,支持根據(jù)指定的一列或多列,把排序列數(shù)據(jù)相近的行排列在一起,提升查詢時的過濾性能,在一定程度上降低存儲成本。


    具體語句2:插入或覆寫動態(tài)分區(qū)數(shù)據(jù)

    --在使用MaxCompute SQL處理數(shù)據(jù)時,分區(qū)列的值在select子句中提供,系統(tǒng)自動根據(jù)分區(qū)列的值將數(shù)據(jù)插入到相應分區(qū)。
    
    
    insert {into|overwrite} table <table_name> partition (<ptcol_name>[, <ptcol_name> ...]) 
    <select_statement> from <from_statement>;
    
    
    ----------------------------------------------------------------------------
    --例子
    --指定一級分區(qū),將數(shù)據(jù)插入目標表。
    insert overwrite table sale_detail_dypart partition (sale_date='2013', region)
    select shop_name,customer_id,total_price,region from sale_detail;
    
    
    --將源表sale_detail中的數(shù)據(jù)插入到目標表sale_detail_dypart。
    insert overwrite table sale_detail_dypart partition (sale_date, region)
    select shop_name,customer_id,total_price,sale_date,region from sale_detail;


    參數(shù)說明:

    table_name:必填。需要插入數(shù)據(jù)的目標表名。

    ptcol_name:必填。目標表分區(qū)列的名稱。

    select_statement:必填。select子句,從源表中查詢需要插入目標表的數(shù)據(jù)。

    from_statement:必填。from子句,表示數(shù)據(jù)來源。例如,源表名稱。


    具體語句3:更新或刪除數(shù)據(jù)

    --刪除操作:用于刪除Transactional或Delta Table表中滿足指定條件的單行或多行數(shù)據(jù)。
    delete from <table_name> [where <where_condition>];
    
    
    
    
    
    
    --清空列數(shù)據(jù):將不再使用的列數(shù)據(jù)從磁盤刪除并置NULL,從而達到降低存儲成本的目的。
    ALTER TABLE <table_name> 
               [partition ( <pt_spec>[, <pt_spec>....] )] 
               CLEAR COLUMN column1[, column2, column3, ...]
                                   [without touch];
    
    
    
    
    --更新操作:用于將Transactional表或Delta Table表中行對應的單列或多列數(shù)據(jù)更新為新值。
    --方式1
    update <table_name> set <col1_name>=<value1> [, <col2_name>=<value2> ...] [WHERE <where_condition>];
    --方式2
    update <table_name> set (<col1_name> [, <col2_name> ...])=(<value1> [, <value2> ...])[WHERE <where_condition>];
    --方式3
    UPDATE <table_name>
           SET <col1_name>=<value1> [ , <col2_name>=<value2> , ... ]
            [ FROM <additional_tables> ]
            [ WHERE <where_condition> ]


    參數(shù)說明:

    table_name:必填。

    where_condition:可選。WHERE子句,用于篩選滿足條件的數(shù)據(jù)。

    partition:指定分區(qū),若未指定,則表示操作所有分區(qū)。

    pt_spec:分區(qū)描述。

    without touch:表示不更新LastDataModifiedTime。

    col1_name、col2_name:待修改行對應的列名稱。

    value1、value2:至少更新一個列值。修改后的新值。

    where_condition:可選。WHERE子句,用于篩選滿足條件的數(shù)據(jù)。

    additional_tables:可選,from子句。


    具體語句4:merge into

    merge into <target_table> as <alias_name_t> using <source expression|table_name> as <alias_name_s>
    --從on開始對源表和目標表的數(shù)據(jù)進行關聯(lián)判斷。
    on <boolean expression1>
    --when matched…then指定on的結(jié)果為True的行為。多個when matched…then之間的數(shù)據(jù)無交集。
    when matched [and <boolean expression2>] then update set <set_clause_list>
    when matched [and <boolean expression3>] then delete 
    --when not matched…then指定on的結(jié)果為False的行為。
    when not matched [and <boolean expression4>] then insert values <value_list>
    
    
    
    
    ----------------------------------------------------------------------------
    --例子
    --執(zhí)行merge into操作,對符合on條件的數(shù)據(jù)用源表的數(shù)據(jù)對目標表進行更新操作,對不符合on條件并且源表中滿足event_type為I的數(shù)據(jù)插入目標表。命令示例如下:
    merge into acid_address_book_base1 as t using tmp_table1 as s 
    on s.id=t.id and t.year='2020' and t.month='08' and t.day='20' and t.hour='16' 
    when matched then update set t.first_name=s.first_name, t.last_name=s.last_name, t.phone=s.phone 
    when not matched and (s._event_type_='I') then insert values(s.id, s.first_name, s.last_name,s.phone,'2020','08','20','16');


    參數(shù)說明:

    target_table:必填。目標表名稱,必須是實際存在的表。

    alias_name_t:必填。目標表的別名。

    source expression|table_name:必填。關聯(lián)的源表名稱、視圖或子查詢。

    alias_name_s:必填。關聯(lián)的源表、視圖或子查詢的別名。

    boolean expression1:必填。BOOLEAN類型判斷條件,判斷結(jié)果必須為True或False。

    boolean expression2:可選。update、delete、insert操作相應的BOOLEAN類型判斷條件。

    set_clause_list:當出現(xiàn)update操作時必填。

    value_list:當出現(xiàn)insert操作時必填。


    具體語句5:Values

    --insert … values
    insert into table <table_name>
    [partition (<pt_spec>)][(<col1_name> ,<col2_name>,...)] 
    values (<col1_value>,<col2_value>,...),(<col1_value>,<col2_value>,...),...
    
    
    --values table
    values (<col1_value>,<col2_value>,...),(<col1_value>,<col2_value>,...),<table_name> (<col1_name> ,<col2_name>,...)...


    參數(shù)說明:

    table_name:必填。待插入數(shù)據(jù)的表名稱。

    pt_spec:可選。需要插入數(shù)據(jù)的目標分區(qū)信息。

    col_name:可選。需要插入數(shù)據(jù)的目標列名稱。

    col_value:可選。目標表中列對應的列值。


    具體語句6:Load

    --將Hologres、OSS、Amazon Redshift、BigQuery外部存儲的CSV格式或其他開源格式數(shù)據(jù)導入MaxCompute的表或表的分區(qū)。
    {load overwrite|into} table <table_name> [partition (<pt_spec>)]
    from location <external_location>
    stored by <StorageHandler>
    [with serdeproperties (<Options>)];
    
    
    ----------------------------------------------------------------------------
    --例子
    load overwrite table xxxx_data_csv_load
    from
    location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/mc-test/data_location/'
    stored by 'com.aliyun.odps.CsvStorageHandler'
    with serdeproperties (
      'odps.properties.rolearn'='acs:ram::xxxxx:role/aliyunodpsdefaultrole',   --AliyunODPSDefaultRole的ARN信息,可通過RAM角色管理頁面獲取。
      'odps.text.option.delimiter'=','
    );


    參數(shù)說明:

    table_name:必填。需要插入數(shù)據(jù)的目標表名稱。

    pt_spec:可選。需要插入數(shù)據(jù)的目標表分區(qū)信息。

    external_location:必填。指定讀取外部存儲數(shù)據(jù)的OSS目錄。

    StorageHandler:必填。指定內(nèi)置的StorageHandler名稱。

    Options:可選。指定外部表相關參數(shù)。


    具體語句7:Unload

    --將MaxCompute的數(shù)據(jù)導出至OSS、Hologres外部存儲,OSS支持以CSV格式或其他開源格式存儲數(shù)據(jù)。
    unload from {<select_statement>|<table_name> [partition (<pt_spec>)]} 
    into 
    location <external_location>
    stored by <StorageHandler>
    [with serdeproperties ('<property_name>'='<property_value>',...)];
    
    
    ----------------------------------------------------------------------------
    --例子
    --控制導出文件個數(shù):設置單個Worker讀取MaxCompute表數(shù)據(jù)的大小,單位為MB。由于MaxCompute表有壓縮,導出到OSS的數(shù)據(jù)一般會膨脹4倍左右。
    set odps.stage.mapper.split.size=256;
    --導出數(shù)據(jù)。
    unload from sale_detail partition (sale_date='2013',region='china')
    into
    location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/mc-unload/data_location'
    stored by 'com.aliyun.odps.TsvStorageHandler'
    with serdeproperties ('odps.properties.rolearn'='acs:ram::139699392458****:role/AliyunODPSDefaultRole', 'odps.text.option.gzip.output.enabled'='true');


    參數(shù)說明:

    select_statement:select查詢子句,

    table_name、pt_spec:使用表名稱或表名稱加分區(qū)名稱的方式指定需要導出的數(shù)據(jù)。

    external_location:必填。

    StorageHandler:必填。指定內(nèi)置的StorageHandler名稱。

    <property_name>'='<property_value>':可選。property_name為屬性名稱,property_value為屬性值。


    具體語句8:Explain

    --分析查詢語句或表結(jié)構(gòu)來分析性能瓶頸
    explain <dml query>;
    ----------------------------------------------------------------------------
    --例子
    explain 
    select a.customer_id as ashop, sum(a.total_price) as ap,count(b.total_price) as bp 
    from (select * from sale_detail_jt where sale_date='2013' and region='china') a 
    inner join (select * from sale_detail where sale_date='2013' and region='china') b 
    on a.customer_id=b.customer_id 
    group by a.customer_id 
    order by a.customer_id 
    limit 10;


    參數(shù)說明:

    dml query:必填。select語句。


    具體語句9:公用表表達式

    --臨時命名結(jié)果集,用于簡化SQL,可以更好地提高SQL語句的可讀性與執(zhí)行效率
    with 
         <cte_name> as
        (
          <cte_query>
        )
        [,<cte_name2>  as 
         (
           <cte_query2>
         )
         ,……]
    
    
    ----------------------------------------------------------------------------
    --例子    
    with 
      a as (select * from src where key is not null),
      b as (select  * from src2 where value > 0),
      c as (select * from src3 where value > 0),
      d as (select a.key, b.value from a join b on a.key=b.key),
      e as (select a.key,c.value from a left outer join c on a.key=c.key and c.key is not null)
    insert overwrite table srcp partition (p='abc')
    select * from d union all select * from e;


    參數(shù)說明:

    cte_name:必填。CTE的名稱,不能與當前with子句中的其他CTE的名稱相同。查詢中任何使用到cte_name標識符的地方,均指CTE。

    cte_query:必填。一個select語句。select的結(jié)果集用于填充CTE。


    ?DQL


    • SELECT語句


    1. SELECT語法

    [with <cte>[, ...] ]
    SELECT [all | distinct] <SELECT_expr>[, <except_expr>][, <replace_expr>] ...
           from <table_reference>
           [where <where_condition>]
           [group by {<col_list>|rollup(<col_list>)}]
           [having <having_condition>]
           [window <window_clause>]
           [order by <order_condition>]
           [distribute by <distribute_condition> [sort by <sort_condition>]|[ cluster by <cluster_condition>] ]
           [limit <number>]


    下面將介紹SELECT命令格式及如何實現(xiàn)嵌套查詢、分組查詢、排序等操作。


    2. SELECT語序

    --語法順序
    from <table_reference>
    [where <where_condition>]
    [group by <col_list>]
    [having <having_condition>]
    [window <window_name> AS (<window_definition>)]
    [qualify <expression>]
    select [all | distinct] <select_expr>, <select_expr>, ...
    [order by <order_condition>]
    [distribute by <distribute_condition> [sort by <sort_condition>] ]
    [limit <number>]


    場景1:from->where->group by->having->select->order by->limit

    場景2:from->where->select->distribute by->sort by


    3. WITH子句

    with 
    A as (SELECT 1 as C),
    B as (SELECT * from A) 
    SELECT * from B;


    在同一WITH子句中的CTE必須具有唯一的名字。

    在WITH子句中定義的CTE僅對在同一WITH子句中的其他CTE可以使用。


    4. 列表達式

    ----------------------------------------------------------------------------
    --例子 
    --讀取表xxxx_detail的列shop_name
    SELECT xxxx_name from xxxx_detail;
    --查詢表xxxx_detail中region列數(shù)據(jù),如果有重復值時僅顯示一條。
    SELECT distinct region from xxxx_detail;
    --選出xxxx_detail表中列名不為xxxx_name的所有列
    SELECT `(xxxx_name)?+.+` from xxxx_detail;
    --去重多列時,distinct的作用域是SELECT的列集合,不是單個列。
    SELECT distinct region, xxxx_date from xxxx_detail;


    用列名指定要讀取的列。

    用星號(*)代表查詢所有的列。

    可以使用正則表達式。

    在選取的列名前可以使用distinct去掉重復字段,只返回去重后的值。


    5. 排除列

    --讀取xxxx_detail表的數(shù)據(jù),并排除region列的數(shù)據(jù)。
    ----------------------------------------------------------------------------
    --例子
    SELECT * except(region) from xxxx_detail;


    當希望讀取表內(nèi)大多數(shù)列的數(shù)據(jù),同時要排除表中少數(shù)列的數(shù)據(jù)時。

    表示讀取表數(shù)據(jù)時會排除指定列(col1、col2)的數(shù)據(jù)。


    6. WHERE

    --配合關系運算符,篩選滿足指定條件的數(shù)據(jù)。關系運算符包含:
      >、<、=、>=、<=、<>
      like、rlike
      in、not in
      between…and
    ----------------------------------------------------------------------------
    --例子
    SELECT * 
    from xxxx_detail
    where xxxx_date >='2008' and xxxx_date <='2014';
    --等價于如下語句。
    SELECT * 
    from xxxx_detail 
    where xxxx_date between '2008' and '2014';


    where子句為過濾條件。如果表是分區(qū)表,可以實現(xiàn)列裁剪。


    7. GROUP BY

    ----------------------------------------------------------------------------
    --例子
    
    
    --直接使用輸入表列名region作為group by的列,即以region值分組
    SELECT region from xxxx_detail group by region;
    
    
    --以region值分組,返回每一組的銷售額總量。
    SELECT sum(xxxx_price) from xxxx_detail group by region;
    
    
    --以region值分組,返回每一組的region值(組內(nèi)唯一)及銷售額總量。
    SELECT region, sum (xxxx_price) from xxxx_detail group by region;


    group by操作優(yōu)先級高于SELECT操作,因此group by的取值是SELECT輸入表的列名或由輸入表的列構(gòu)成的表達式。需要注意的是:

    group by取值為正則表達式時,必須使用列的完整表達式。

    SELECT語句中沒有使用聚合函數(shù)的列必須出現(xiàn)在GROUP BY中。


    8. HAVING

    ----------------------------------------------------------------------------
    --例子
    --為直觀展示數(shù)據(jù)呈現(xiàn)效果,向sale_detail表中追加數(shù)據(jù)。
    insert into sale_detail partition (sale_date='2014', region='shanghai') 
      values ('null','c5',null),('s6','c6',100.4),('s7','c7',100.5);
    --使用having子句配合聚合函數(shù)實現(xiàn)過濾。
    SELECT region,sum(total_price) from sale_detail 
    group by region 
    having sum(total_price)<305;


    通常HAVING子句與聚合函數(shù)一起使用,實現(xiàn)過濾。


    9. ORDER BY

    ----------------------------------------------------------------------------
    --例子
    
    
    --查詢表xxxx_detail的信息,并按照xxxx_price升序排列前2條。
    SELECT * from xxxx_detail order by xxxx_price limit 2;
    
    
    --將表xxx_detail按照xxxx_price升序排序后,輸出從第3行開始的3行數(shù)據(jù)。
    SELECT xxxx_id,xxxx_price from xxxx_detail order by xxxx_price limit 3 offset 2;


    默認對數(shù)據(jù)進行升序排序,如果降序排序,需要使用desc關鍵字。

    order by默認要求帶limit數(shù)據(jù)行數(shù)限制,沒有l(wèi)imit會返回報錯。


    10. DISTRIBUTE BY哈希分片

    ----------------------------------------------------------------------------
    --例子
    
    
    --查詢表xxxx_detail中的列region值并按照region值進行哈希分片。
    SELECT region from xxxx_detail distribute by region;
    --等價于如下語句。
    SELECT region as r from xxxx_detail distribute by region;
    SELECT region as r from xxxx_detail distribute by r;


    distribute by控制Map(讀數(shù)據(jù))的輸出在Reducer中是如何劃分的,如果不希望Reducer的內(nèi)容存在重疊,或需要對同一分組的數(shù)據(jù)一起處理,可以使用distribute by來保證同組數(shù)據(jù)分發(fā)到同一個Reducer中。


    11. SORT BY局部排序

    ----------------------------------------------------------------------------
    --例子
    
    
    --查詢表xxxx_detail中的列region和xxxx_price的值并按照region值進行哈希分片,然后按照xxxx_price對哈希分片結(jié)果進行局部升序排序。
    SELECT region,xxxx_price from xxxx_detail distribute by region sort by xxxx_price;
    
    
    --查詢表xxxx_detail中的列region和xxxx_price的值并按照region值進行哈希分片,然后按照xxxx_price對哈希分片結(jié)果進行局部降序排序。
    SELECT region,xxxx_price from xxxx_detail distribute by region sort by xxxx_price desc;
    
    
    --如果sort by語句前沒有distribute by,sort by會對每個Reduce中的數(shù)據(jù)進行局部排序。
    SELECT region,xxxx_price from xxxx_detail sort by xxxx_price desc;


    sort by默認對數(shù)據(jù)進行升序排序,如果降序排序,需要使用desc關鍵字。

    如果sort by語句前有distribute by,sort by會對distribute by的結(jié)果按照指定的列進行排序。


    12. LIMIT限制輸出行數(shù)

    SELECT * FROM xxxxx.xxxx_xxxx_xxxx
    WHERE ds=20240520
    LIMIT 100;


    limit <number>中的number是常數(shù),用于限制輸出行數(shù),取值范圍為int32位取值范圍。


    • 子查詢


    1. 基礎子查詢

    --格式1
    select <select_expr> from (<select_statement>) [<sq_alias_name>];
    
    
    --格式2
    select (<select_statement>) from <table_name>;


    普通查詢操作的對象是目標表,但是查詢的對象也可以是另一個select語句,這種查詢?yōu)樽硬樵儭T趂rom子句中,子查詢可以被當作一張表,與其他表或子查詢進行join操作。


    2. IN SUBQUERY

    --in subquery與left semi join用法類似
    --格式一
    select<select_expr1>from<table_name1>where<select_expr2>
      in(select<select_expr3>from<table_name2>);
    --等效于leftsemijoin如下語句。
    select<select_expr1>from<table_name1><alias_name1>leftsemijoin<table_name2><alias_name2>
      on<alias_name1>.<select_expr2>=<alias_name2>.<select_expr3>;
    
    
    --格式二
    select<select_expr1>from<table_name1>where<select_expr2>
      in(select<select_expr3>from<table_name2>where
         <table_name1>.<col_name>=<table_name2>.<col_name>);
    
    
    ----------------------------------------------------------------------------
    --例子
    set odps.sql.allow.fullscan=true;
    select * from xxxx_detail where xxxx_price in (select xxxx_price from shop);
    
    
    set odps.sql.allow.fullscan=true;
    select * from xxxx_detail where xxxx_price 
      in (select xxxx_price from shop where xxxx_id=shop.xxxx_id);


    select_expr1:必填。格式為col1_name, col2_name, 正則表達式,...,表示待查詢的普通列、分區(qū)列或正則表達式。

    table_name1、table_name2:必填。表的名稱。

    select_expr2、select_expr3:必填。表示table_name1和table_name2互相映射的列名。

    col_name:必填。表的列名。


    3. NOT IN SUBQUERY

    --如果查詢目標表的指定列名中有任意一行為NULL,則not in表達式值為NULL,導致where條件不成立,無數(shù)據(jù)返回
    select <select_expr1> from <table_name1> where <select_expr2> not in (select <select_expr2> from <table_name2>);
    --等效于left anti join如下語句。
    select <select_expr1> from <table_name1> <alias_name1> 
      left anti join <table_name2> <alias_name2> on <alias_name1>.<select_expr1>=<alias_name2>.<select_expr2>;
    
    
    ----------------------------------------------------------------------------
    --例子
    --創(chuàng)建一張新表shop1并追加數(shù)據(jù)。
    create table shop1 as select xxxx_name,xxxx_id,xxxx_price from xxxx_detail;
    insert into shop1 values ('s8','c1',100.1);
    select * from shop1 where xxxx_name not in (select xxxx_name from xxxx_detail);
    
    
    set odps.sql.allow.fullscan=true;
    select * from shop1 where xxxx_name not in (select xxxx_name from xxxx_detail where xxxx_id=shop1.xxxx_id);


    select_expr1:必填。格式為col1_name, col2_name, 正則表達式,...,表示待查詢的普通列、分區(qū)列或正則表達式。

    table_name1、table_name2:必填。表的名稱。

    select_expr2、select_expr3:必填。表示table_name1和table_name2互相映射的列名。

    col_name:必填。表的列名。


    4. EXISTS SUBQUERY

    --使用exists subquery時,當子查詢中有至少一行數(shù)據(jù)時,返回True,否則返回False。
    select <select_expr> from <table_name1> where exists 
       (select <select_expr> from <table_name2> 
        where <table_name2_colname>=<table_name1>.<colname>
       );
    
    
    ----------------------------------------------------------------------------
    --例子
    set odps.sql.allow.fullscan=true;
    select * from xxxx_detail where exists 
    (select * from shop where customer_id=xxxx_detail.xxxx_id);
    --等效于以下語句。
    select * from xxxx_detail a left semi join shop b on a.xxxx_id=b.xxxx_id;


    select_expr:必填。格式為col1_name, col2_name, 正則表達式,...,表示待查詢的普通列、分區(qū)列或正則表達式。

    table_name1、table_name2:必填。表的名稱。

    col_name:必填。表的列名。


    5. NOT EXISTS SUBQUERY

    --當子查詢中無數(shù)據(jù)時,返回True,否則返回False
    select <select_expr> from <table_name1> where not exists   
      (select <select_expr> from <table_name2> where <table_name2_colname>=<table_name1>.<colname>);
    
    
    ----------------------------------------------------------------------------
    --例子
    set odps.sql.allow.fullscan=true;
    select * from xxxx_detail where not exists (select * from shop where xxxx_name=xxxx_detail.xxxx_name);
    --等效于以下語句。
    select * from xxxx_detail a left anti join shop b on a.shop_name=b.xxxx_name;


    select_expr:必填。格式為col1_name, col2_name, 正則表達式,...,表示待查詢的普通列、分區(qū)列或正則表達式。

    table_name1、table_name2:必填。表的名稱。

    col_name:必填。表的列名。


    6. SCALAR SUBQUERY

    --當子查詢的輸出結(jié)果為單行單列時,可以做為標量使用,即可以參與標量運算。
    select <select_expr> from <table_name1> where 
      (<select count(*) from <table_name2> where <table_name2_colname>=<table_name1>.<colname>) 
      <標量運算符> <scalar_value>;
    
    
    ----------------------------------------------------------------------------
    --例子
    set odps.sql.allow.fullscan=true;
    select * from shop where 
      (select count(*) from xxxx_detail where xxxx_detail.xxxx_name=shop.xxxx_name) >=1;


    select_expr:必填。格式為col1_name, col2_name, 正則表達式。

    table_name1、table_name2:必填。表的名稱。

    col_name:必填。表的列名。

    標量運算符:必填。例如大于(>)、小于(<)、等于(=)。

    scalar_value:必填。標量值


    • 交集,并集和補集


    1. 交集

    --取交集不去重。
    <select_statement1> intersect all <select_statement2>;
    --取交集并去重。intersect效果等同于intersect distinct。
    <select_statement1> intersect [distinct] <select_statement2>;
    
    
    ----------------------------------------------------------------------------
    --例子
    select * from values (1, 2), (1, 2), (3, 4), (5, 6) t(a, b) 
    intersect all 
    select * from values (1, 2), (1, 2), (3, 4), (5, 7) t(a, b);
    --結(jié)果
    +------------+------------+
    | a          | b          |
    +------------+------------+
    | 1          | 2          |
    | 3          | 4          |
    +------------+------------+


    select_statement1、select_statement2:必填。

    distinct:可選。對兩個數(shù)據(jù)集取交集的結(jié)果去重。


    2. 并集

    --取并集不去重。
    <select_statement1> union all <select_statement2>;
    --取并集并去重。
    <select_statement1> union [distinct] <select_statement2>;
    
    
    ----------------------------------------------------------------------------
    --例子
    select * from values (1, 2), (1, 2), (3, 4) t(a, b) 
    union all 
    select * from values (1, 2), (1, 4) t(a, b);
    --結(jié)果
    +------------+------------+
    | a          | b          |
    +------------+------------+
    | 1          | 2          |
    | 1          | 2          |
    | 3          | 4          |
    | 1          | 2          |
    | 1          | 4          |
    +------------+------------+


    select_statement1、select_statement2:必填。select語句。

    distinct:可選。對兩個數(shù)據(jù)集取并集的結(jié)果去重。


    3. 補集

    --取補集不去重。
    <select_statement1> except all <select_statement2>;
    <select_statement1> minus all <select_statement2>;
    --取補集并去重。
    <select_statement1> except [distinct] <select_statement2>;
    <select_statement1> minus [distinct] <select_statement2>;
    
    
    ----------------------------------------------------------------------------
    --例子
    select * from values (1, 2), (1, 2), (3, 4), (3, 4), (5, 6), (7, 8) t(a, b)
    except all 
    select * from values (3, 4), (5, 6), (5, 6), (9, 10) t(a, b);
    --結(jié)果
    +------------+------------+
    | a          | b          |
    +------------+------------+
    | 1          | 2          |
    | 1          | 2          |
    | 3          | 4          |
    | 7          | 8          |
    +------------+------------+


    select_statement1、select_statement2:必填。select語句。

    distinct:可選。對取補集的結(jié)果去重。


    • JOIN語句


    這里先放一張示意圖:


    --基本格式
    SELECT column1, column2, ...
    FROM table1
    {left outer|right outer|full outer|inner|natural} 
    JOIN table2 
    ON condition;


    參數(shù)說明:

    column1, column2, ...:要選擇的字段名稱,可以為多個字段。如果不指定字段名稱,則會選擇所有字段。

    table1:要連接的第一個表。

    table2:要連接的第二個表。

    condition:連接條件,用于指定連接方式。


    左連接(left outer join)

    可簡寫為left join

    返回左表中的所有記錄,即使右表中沒有與之匹配的記錄。

    右連接(right outer join)

    可簡寫為right join

    返回右表中的所有記錄,即使左表中沒有與之匹配的記錄。

    全連接(full outer join)

    可簡寫為full join

    返回左右表中的所有記錄。

    內(nèi)連接(inner join)

    關鍵字inner可以省略

    左右表中至少存在一個匹配行時,inner join返回數(shù)據(jù)行。

    自然連接(natural join)

    參與join的兩張表根據(jù)字段名稱自動決定連接字段。

    支持outer natural join,支持使用using子句執(zhí)行join,輸出字段中公共字段只出現(xiàn)一次。

    隱式連接

    即不指定join關鍵字執(zhí)行連接。

    多路連接

    多路join連接。支持通過括號指定join的優(yōu)先級,括號內(nèi)的join優(yōu)先級較高。


    • 半連接和mapjoin


    1. SEMI JOIN

    MaxCompute支持半連接操作,通過右表過濾左表的數(shù)據(jù),使右表的數(shù)據(jù)不出現(xiàn)在結(jié)果集中,可以提高查詢性能。

    2. LEFT SEMI JOIN

    當join條件成立時,返回左表中的數(shù)據(jù)。如果左表中滿足指定條件的某行數(shù)據(jù)在右表中出現(xiàn)過,則此行保留在結(jié)果集中。

    3. LEFT ANTI JOIN

    當join條件不成立時,返回左表中的數(shù)據(jù)。如果左表中滿足指定條件的某行數(shù)據(jù)沒有在右表中出現(xiàn)過,則此行保留在結(jié)果集中。

    4. MAPJOIN HINT

    當對一個大表和一個或多個小表執(zhí)行join操作時,可以在select語句中顯式指定mapjoin Hint提示以提升查詢性能。

    5. 在select語句中,使用Hint提示/*+ mapjoin(<table_name>) */才會執(zhí)行mapjoin

    引用小表或子查詢時,需要引用別名。

    mapjoin支持小表為子查詢。

    在mapjoin中,可以使用不等值連接或or連接多個條件。您可以通過不寫on語句而通過mapjoin on 1=1的形式,實現(xiàn)笛卡爾乘積的計算。

    mapjoin中多個小表用英文逗號(,)分隔,例如/*+ mapjoin(a,b,c)*/。


    --允許分區(qū)表的全表掃描
    SET odps.sql.allow.fullscan=true;
    
    
    -- 使用mapjoin查詢
    select /*+ mapjoin(a) */
            a.xxxx_name,
            a.xxxx_price,
            b.xxxx_price
    from xxxx_detail_sj a join xxxx_detail b
    on a.xxxx_price < b.xxxx_price or a.xxxx_price + b.xxxx_price < 500;


    • SKEWJOIN HINT


    其原理圖:


    --方法1:Hint表名(注意Hint的是表的alias)。
    select /*+ skewjoin(a) */ * from T0 a join T1 b on a.c0=b.c0 and a.c1=b.c1;
    
    
    --方法2:Hint表名和認為可能產(chǎn)生傾斜的列,例如表a的c0和c1列存在數(shù)據(jù)傾斜。
    select /*+ skewjoin(a(c0, c1)) */ * from T0 a join T1 b on a.c0=b.c0 and a.c1=b.c1 and a.c2=b.c2;
    
    
    --方法3:Hint表名和列,并提供發(fā)生傾斜的key值。如果是STRING類型,需要加上引號。例如(a.c0=1 and a.c1="2")和(a.c0=3 and a.c1="4")的值都存在數(shù)據(jù)傾斜。
    select /*+ skewjoin(a(c0, c1)((1, "2"), (3, "4"))) */ * from T0 a join T1 b on a.c0=b.c0 and a.c1=b.c1 and a.c2=b.c2;


    當兩張表Join存在熱點,導致出現(xiàn)長尾問題時:

    可以通過取出熱點key,將數(shù)據(jù)分為熱點數(shù)據(jù)和非熱點數(shù)據(jù)兩部分處理,最后合并的方式,提高Join效率。


    • HAVING子句

    --格式
    SELECT column_name, aggregate_function(column_name)
    FROM table_name
    WHERE column_name operator value
    GROUP BY column_name
    HAVING aggregate_function(column_name) operator value
    
    
    --例子
    SELECT Customer,SUM(OrderPrice) FROM Orders
    GROUP BY Customer
    HAVING SUM(OrderPrice)<2000


    MaxCompute SQL的WHERE關鍵字無法與聚合函數(shù)一起使用。

    此時可以使用HAVING子句來實現(xiàn)。


    表同步


    ?在線表同步ODPS


    這里以MySQL同步ODPS為例子,其他表同步過程也類似。


    首先介紹一下步驟:

    Step1:進入dataworks,選擇:數(shù)據(jù)開發(fā)(DataStudio) ——> 數(shù)據(jù)集成 ——> Di數(shù)據(jù)同步 節(jié)點:


    Step2:配置來源去向

    • 數(shù)據(jù)來源:數(shù)據(jù)源選擇 “MySQL” ,填入要同步的MySQL的數(shù)據(jù)表名,會自動搜索到對應的物理表;

    • 數(shù)據(jù)去向:數(shù)據(jù)源選擇“ODPS”,odps的目標表可以先建好,也可以使用“一鍵生成目標表” 的功能(推薦,簡單高效);

    • 配置好來源去向后,源頭表字段和目標表字段會自動映射匹配;

    Step3: 填好調(diào)度配置

    調(diào)度參數(shù),注意參數(shù)值不同,展示的時間也不同

    注意調(diào)度周期,天級,小時級或其他周期

    設置好調(diào)度依賴,即依賴哪些上級文件的產(chǎn)出,若無可填根節(jié)點:


    Step4:同步信息填寫完成后,在調(diào)度配置里配置好調(diào)度信息,保存——>發(fā)布——>補數(shù)據(jù) 即可:


    接下來,是一些經(jīng)驗總結(jié)

    1、“數(shù)據(jù)來源”的“數(shù)據(jù)過濾”,不填表示全量同步MySQL的數(shù)據(jù);也可以使用類似(gmt_create='${bizdate}')條件來過濾,每次增量同步MySQL的數(shù)據(jù)

    2、“數(shù)據(jù)去向”的“一鍵生成目標表”功能,建表DDL語句需要人工檢查下:

    • 填寫好lifecycle,分區(qū)配置
    • 列名不要與odpsSQL關鍵字沖突
    • 可以自定義修改表名

    3、“數(shù)據(jù)去向”的“分區(qū)信息”,當建的是分區(qū)表時,會自動出現(xiàn)該處的分區(qū)信息配置;若建的是非分區(qū)表,則不必配置

    4、調(diào)度配置中,可以按需選擇天、小時或其他時間粒度調(diào)度任務

    5、非該odps項目空間的表不能在該odps項目空間做同步任務

    6、odps個別字段內(nèi)容太長,超出mysql表的該字段存儲限制,也會導致寫入idb失敗,報臟數(shù)據(jù)(修改idb表字段類型,可將對應字段類型修改為 longtext)

    7、idb表字段設為非null,但odps對應字段存在 null值,會導致寫入idb失敗,報臟數(shù)據(jù)(修改idb表定義,將對應字段改默認為null)

    8、odps字段和idb字段不必非得一對一保持應,可以手動選擇相關字段 連線 ,odps和idb字段可各有未參與同步的字段(注意:idb字段的剩余字段必須是可以自動填充或默認為null類型的)


    ?ODPS導入Hologres


    目前對于需要周期性導入ODPS分區(qū)表數(shù)據(jù)到Hologres, Holo提供了兩種導入方式:

    方式一:一鍵可視化導入并且周期性導入,詳情見datastudio一鍵導入

    方式二:使用sql導入,詳情見hologres sql


    • 一鍵可視化導入


    1. 新建任務,在數(shù)據(jù)開發(fā)單擊一鍵數(shù)據(jù)同步,并填寫節(jié)點信息。


    2. 配置信息,填寫同步信息。


    3. 參數(shù)說明

    參數(shù)

    配置項

    說明

    備注

    MaxCompute源表選擇

    目標連接

    Hologres的實例名

    目標庫

    Hologres的DB名

    外部表來源

    • 已有外部表
    • 新建外部表
    • 已有外部表表示已經(jīng)提前在Hologres中映射MaxCompute數(shù)據(jù)的外部表
    • 新建外部表表示無相應的外部表,需要同步時新建

    外部表表名字

    已有的外部表表名

    外部表用于映射MaxCompute數(shù)據(jù),需要與同步數(shù)據(jù)的MaxCompute表對應

    目標表設置

    目標Schema

    當前DB下的schema名

    默認為public,也可以選擇新建schema并使用

    目標表名

    要導入數(shù)據(jù)的表名

    需要同步表數(shù)據(jù)的內(nèi)表名稱,如已有表,執(zhí)行后原表和數(shù)據(jù)將被刪除重建

    目標表描述

    為目標表添加comment

    同步設置

    同步字段

    選擇需要同步的MaxCompute表字段

    可以選擇全部字段,也可以選擇部分字段

    分區(qū)配置

    選擇需要同步的分區(qū)字段

    當前Hologres僅支持一級分區(qū)

    索引配置

    為目標表構(gòu)建索引

    索引的創(chuàng)建可以參見文檔設置表屬性

    SQL Script

    SQL Script

    自動解析出當前運行的SQL,方便參照


    • 保持并運行,執(zhí)行同步任務。任務執(zhí)行完成之后,可以使用Hologres SQL查看數(shù)據(jù)。
    • 周期性調(diào)度


    若是您需要周期性導數(shù)據(jù),需要單機右側(cè)調(diào)度配置進行任務配置,并且保存作業(yè),然后點擊右上角發(fā)布,將作業(yè)發(fā)布至生產(chǎn)環(huán)境進行周期性調(diào)度。



    4. 總結(jié)

    方式一優(yōu)點:可視化操作,簡單快捷,方便小白用戶使用,能滿足一般場景的使用。

    方式一缺點:不支持修改SQL邏輯,若是需要修改,需將SQL Copy再新建一個Hologres SQL節(jié)點,根據(jù)業(yè)務邏輯修改SQL即可。


    • 自寫sql導入


    先介紹一下操作步驟,基本和方式一相同。


    1. 新建業(yè)務流程:選擇左側(cè)菜單欄數(shù)據(jù)開發(fā)--新建--業(yè)務流程,即可創(chuàng)建一個屬于自己的業(yè)務流程。

    2. 輸入業(yè)務流程名稱

    3. 新建Hologres SQL

    4. Hologres開發(fā):打開新建的Hologres SQL選擇對應Hologres實例,既可使用標準的Postgresql語言開發(fā)。


    步驟1:準備MaxCompute表數(shù)據(jù)

    --MaxCompute分區(qū)表DDL
    CREATE TABLE IF NOT EXISTS public_data.dwd_product_movie_basic_info(
      movie_name STRING COMMENT '電影名稱',
      dirctor STRING COMMENT '導演',
      scriptwriter STRING COMMENT '編劇',
      area STRING COMMENT '制片地區(qū)/國家',
      actors STRING COMMENT '主演',
      `type` STRING COMMENT '類型',
      movie_length STRING COMMENT '電影長度',
      movie_date STRING COMMENT '上映日期',
      movie_language STRING COMMENT '語言',
      imdb_url STRING COMMENT 'imdb號'
    ) 
    PARTITIONED BY (ds STRING) STORED AS ALIORC;
    
    
    --查看分區(qū)表的某個分區(qū)數(shù)據(jù)
    SELECT * FROM public_data.xxxx_movie_basic_info WHERE ds='20170112';


    步驟2:Hologres新建外部表


    移步HoloStudio,在SQL Console中新建一張外部表,用于映射MaxCompute源頭表數(shù)據(jù)。外表的字段順序和字段類型需要和MaxCompute一一對應。示例使用import foreign schema語法新建外部表SQL如下:

    import foreign schema public_data limit to (dwd_product_movie_basic_info) 
    from server odps_server into public options(if_table_exist 'update');


    步驟3:Hologres新建真實存儲表


    在Hologres中新建一張真實的存儲表,用于接收并存儲數(shù)據(jù)。因為本次示例是將MaxCompute分區(qū)表導入Hologres分區(qū)表,因此需要在Hologres中創(chuàng)建一張分區(qū)表。

    BEGIN;
    CREATE TABLE "public"."holo_dwd_product_movie_basic_info" (
      "movie_name" text,
      "dirctor" text,
      "scriptwriter" text,
      "area" text,
      "actors" text,
      "type" text,
      "movie_length" text,
      "movie_date" text,
      "movie_language" text,
      "imdb_url" text,
      "ds" text
    )
    PARTITION BY LIST (ds);
    CALL SET_TABLE_PROPERTY('"public"."holo_dwd_product_movie_basic_info"', 'orientation', 'column');
    CALL SET_TABLE_PROPERTY('"public"."holo_dwd_product_movie_basic_info"', 'bitmap_columns', '"movie_name","dirctor","scriptwriter","area","actors","type","movie_length","movie_date","movie_language","imdb_url","ds"');
    CALL SET_TABLE_PROPERTY('"public"."holo_dwd_product_movie_basic_info"', 'dictionary_encoding_columns', '"movie_name:auto","dirctor:auto","scriptwriter:auto","area:auto","actors:auto","type:auto","movie_length:auto","movie_date:auto","movie_language:auto","imdb_url:auto","ds:auto"');
    CALL SET_TABLE_PROPERTY('"public"."holo_dwd_product_movie_basic_info"', 'time_to_live_in_seconds', '3153600000');
    comment on column "public"."holo_dwd_product_movie_basic_info"."movie_name" is '電影名稱';
    comment on column "public"."holo_dwd_product_movie_basic_info"."dirctor" is '導演';
    comment on column "public"."holo_dwd_product_movie_basic_info"."scriptwriter" is '編劇';
    comment on column "public"."holo_dwd_product_movie_basic_info"."area" is '制片地區(qū)/國家';
    comment on column "public"."holo_dwd_product_movie_basic_info"."actors" is '主演';
    comment on column "public"."holo_dwd_product_movie_basic_info"."type" is '類型';
    comment on column "public"."holo_dwd_product_movie_basic_info"."movie_length" is '電影長度';
    comment on column "public"."holo_dwd_product_movie_basic_info"."movie_date" is '上映日期';
    comment on column "public"."holo_dwd_product_movie_basic_info"."movie_language" is '語言';
    comment on column "public"."holo_dwd_product_movie_basic_info"."imdb_url" is 'imdb號';
    COMMIT;


    步驟4:新建分區(qū)子表數(shù)據(jù)開發(fā)


    在hologres sql中另開一個作業(yè),用于分區(qū)表跑調(diào)度。

    --創(chuàng)建臨時分區(qū)子表
    BEGIN;
    CREATE TABLE IF NOT EXISTS "public".tmp_holo_dwd_product_movie_basic_info_${bizdate}  (
      "movie_name" text,
      "dirctor" text,
      "scriptwriter" text,
      "area" text,
      "actors" text,
      "type" text,
      "movie_length" text,
      "movie_date" text,
      "movie_language" text,
      "imdb_url" text,
      "ds" text
    );
    COMMIT;
    
    
    --更新外表數(shù)據(jù)
    import foreign schema public_data limit to (dwd_product_movie_basic_info) from server odps_server into public options(if_table_exist 'update');
    
    
    --等待30s再導入Hologres,以防Hologres meta信息更新緩存慢導致的數(shù)據(jù)不一致而同步不成功
    select pg_sleep(30); 
    
    
    --將Maxcompute數(shù)據(jù)導入臨時分區(qū)子表
    INSERT INTO "public".tmp_holo_dwd_product_movie_basic_info_${bizdate} 
    SELECT 
        "movie_name",
        "dirctor",
        "scriptwriter",
        "area",
        "actors",
        "type",
        "movie_length",
        "movie_date",
        "movie_language",
        "imdb_url",
        "ds"
    FROM "public".dwd_product_movie_basic_info
    WHERE ds='${bizdate}';
    
    
    
    
    --導入的場景邏輯比較多,下面有兩個場景供參考,可以根據(jù)業(yè)務邏輯二選一即可
    
    
    --場景1:導入新的分區(qū)數(shù)據(jù)可以參考以下邏輯,
    BEGIN;
    
    
    ALTER TABLE "public".tmp_holo_dwd_product_movie_basic_info_${bizdate} RENAME TO holo_dwd_product_movie_basic_info_${bizdate};
    
    
    --將臨時分區(qū)子表綁定在分區(qū)父表上
    ALTER TABLE "public".holo_dwd_product_movie_basic_info ATTACH PARTITION "public".holo_dwd_product_movie_basic_info_${bizdate} FOR VALUES in ('${bizdate}');
    
    
    COMMIT;
    
    
    
    
    --場景2:重新對歷史分區(qū)數(shù)據(jù)刷新可以參考該邏輯
    BEGIN;
    
    
    ALTER TABLE IF EXISTS "public".holo_dwd_product_movie_basic_info DETACH PARTITION "public".holo_dwd_product_movie_basic_info_${bizdate};
    
    
    DROP TABLE IF EXISTS "public".holo_dwd_product_movie_basic_info_${bizdate};
    
    
    ALTER TABLE "public".tmp_holo_dwd_product_movie_basic_info_${bizdate} RENAME TO holo_dwd_product_movie_basic_info_${bizdate};
    
    
    --將分區(qū)子表綁定在分區(qū)父表上
    ALTER TABLE "public".holo_dwd_product_movie_basic_info ATTACH PARTITION "public".holo_dwd_product_movie_basic_info_${bizdate} FOR VALUES in ('${bizdate}');
    
    
    COMMIT;


    步驟5:調(diào)度配置


    1)基礎屬性配置

    將基礎屬性--參數(shù)賦值為時間節(jié)點,如示例所示:


    2)時間屬性設置

    主要設置時間的重跑屬性,其余參數(shù)可以根據(jù)業(yè)務情況自行設置。


    3)調(diào)度依賴設置

    調(diào)度依賴為root節(jié)點即可(也可以根據(jù)業(yè)務邏輯選擇已有的父節(jié)點)請先單擊自動解析為,然后單擊使用工作空間根節(jié)點,會自動解析出root節(jié)點,然后將自動解析設置為


    步驟6:發(fā)布調(diào)度


    調(diào)度參數(shù)配置完成之后,單擊保存--提交,提交成功后單擊運維前往運維中心。


    步驟7:運維中心發(fā)布


    在跳轉(zhuǎn)出來的運維中心,選擇已提交成功成功的節(jié)點,右鍵單擊節(jié)點,選擇補數(shù)據(jù)--當前節(jié)點。并根據(jù)業(yè)務情況設置節(jié)點配置。


    補完數(shù)據(jù)之后,在補數(shù)據(jù)實例可以看到正在運行的任務,以及任務運行狀態(tài)。


    步驟8:Hologres查看數(shù)據(jù)


    任務執(zhí)行成功之后,將會在Hologres中自動創(chuàng)建對應分區(qū)數(shù)據(jù)的分區(qū)子表,可以返回datastudio,新開一個hologres sql節(jié)點,執(zhí)行語句查詢數(shù)據(jù)是否寫入成功。

    --查看分區(qū)子表數(shù)據(jù)
    select * from holo_dwd_product_movie_basic_info_20170112;
    
    
    --查看分區(qū)父表總數(shù)據(jù)
    select count (*) from holo_dwd_product_movie_basic_info;


    總結(jié):

    方式二優(yōu)點:可按業(yè)務需求進行定制,對sql進行修改,滿足復雜特定場景的需求,包括歷史數(shù)據(jù)格式轉(zhuǎn)換、數(shù)據(jù)清理等;通過SQL導入性能更優(yōu)。

    方式二缺點:有一定學習成本,初學者不太適合,可先通過方式一了解其數(shù)據(jù)同步的流程和原理,再切換到方式二。


    • 流程梳理


    -- 1.創(chuàng)建外表
    CREATE FOREIGN TABLE IF NOT EXISTS ${odps_table_name} (
      "user_id" bigint,
      "user_name" text,
      "ds" text
    )
    SERVER odps_server
    OPTIONS (project_name 'onetag', table_name '${odps_table_name}');
    COMMIT;
    
    
    -- 2.刷新外表的Schema
    IMPORT FOREIGN SCHEMA ${odps_project} LIMIT to
    (
      ${odps_table_name}
    ) 
    FROM SERVER odps_server INTO public 
    OPTIONS(if_table_exist 'update',if_unsupported_type 'error');
    
    
    -- 3.清理潛在的臨時表
    BEGIN ;
    DROP TABLE IF EXISTS ${holo_table_name}_tmp_${bizhour};
    COMMIT ;
    
    
    -- 4.創(chuàng)建臨時表
    BEGIN ;
    CREATE TABLE IF NOT EXISTS "public".${holo_table_name}_tmp_${bizhour} (
      "user_id" bigint,
      "user_name" text,
      "ds" text,
      PRIMARY KEY (user_id,ds)
    );  
    COMMIT;
    
    
    -- 5.通過查詢外表,向臨時表插入數(shù)據(jù)
    INSERT INTO ${holo_table_name}_tmp_${bizhour}
    SELECT *
    FROM public.${odps_table_name}
    WHERE ds='${bizhour}';
    
    
    -- 6.替換子表
    BEGIN ;
    
    
    -- 6.1刪除已經(jīng)存在的子表
    DROP TABLE IF EXISTS ${holo_table_name}_${bizhour};
    
    
    -- 6.2將臨時表改名
    ALTER TABLE ${holo_table_name}_tmp_${bizhour} RENAME TO ${holo_table_name}_${bizhour};
    
    
    -- 6.3將臨時表綁定至指定分區(qū)表
    ALTER TABLE ${holo_table_name} ATTACH PARTITION ${holo_table_name}_${bizhour}
    FOR VALUES IN ('${bizhour}');
    COMMIT ;
    
    
    -- 7. 大量數(shù)據(jù)導入后執(zhí)行ANALYZE分區(qū)表父表操作
    ANALYZE ${holo_table_name};


    注意點:

    • 使用臨時表的原因是為了保證原子性,只有在導入完成后才綁定至分區(qū)表,為了避免導入任務失敗時還需要重新刪除表等操作。
    • 對于更新子表分區(qū)數(shù)據(jù)場景,需要刪除子表和重新綁定臨時表放入一個事務過程中,保證該過程的事務性。
    • MaxCompute的表數(shù)據(jù)更新之后,在Hologres存在緩存延遲(一般為10分鐘內(nèi)),建議在導入數(shù)據(jù)前使用IMPORT FOREIGN SCHEMA語法更新外部表以獲取最新數(shù)據(jù)。
    • 導入MaxCompute數(shù)據(jù)至Hologres時,建議使用SQL導入,不建議使用數(shù)據(jù)集成導入,因為使用SQL導入性能表現(xiàn)更優(yōu)。


    注意事項


    ?調(diào)度配置


    這里強調(diào)一下調(diào)度參數(shù):

    調(diào)度參數(shù)通常會被用于指代某些動態(tài)時間的場景,此場景下,可基于業(yè)務日期和定時時間進行調(diào)度參數(shù)的取值設置。配置調(diào)度參數(shù)前,您可先了解這兩個時間概念,便于后續(xù)設置調(diào)度參數(shù)取值。


    取值方式

    參數(shù)格式

    參數(shù)示例

    相關參考

    基于業(yè)務日期獲取時間數(shù)據(jù)

    通常,使用大括號${...},結(jié)合yyyy、yy、mm及dd自定義組合生成時間參數(shù),獲取業(yè)務日期前后多少年、月、天。

    可通過${yyyymmdd}、${yyyy-mm-dd}等${...}自定義時間格式獲取,例如:

    • ${yyyymmdd±N}
    • ${yyyymmdd±7*N}
    • ${yy±N}
    • ${mm}
    • ${yyyy-mm-dd±N}

    更多賦值示例,請參見自定義參數(shù)${...}

    基于定時時間獲取時間數(shù)據(jù)

    通常,使用中括號$[...],結(jié)合yyyy、yy、mm、dd、hh24、mi及ss自定義組合生成時間參數(shù),獲取定時時間前后多少年、月、天、小時、分鐘、秒。

    可通過$[yyyymmddhh24miss]等$[...]自定義時間格式獲取。例如,取前一天的前一小時,參數(shù)表達式為$[yyyymmdd-1-1/24]。

    • 更多賦值示例,請參見自定義參數(shù)$[...]
    • 取多少小時、分鐘,可能存在跨天問題,跨天時間的參數(shù)處理


    內(nèi)置參數(shù)


    內(nèi)置參數(shù)

    定義

    $bizdate

    業(yè)務日期,格式為yyyymmdd,與自定義參數(shù)${yyyymmdd}取值一致。

    該參數(shù)的應用較為廣泛,日常調(diào)度中默認任務預期運行時間的前一天為業(yè)務日期。

    $cyctime

    任務的定時時間,格式為yyyymmddhh24miss,與自定義參數(shù)$[yyyymmddhh24miss]取值一致。

    $gmtdate

    當前日期,格式為yyyymmdd。

    該參數(shù)默認取當天日期,執(zhí)行補數(shù)據(jù)操作時輸入的日期為業(yè)務日期+1。

    $bizmonth

    業(yè)務月份,格式為yyyymm。

    • 如果業(yè)務日期的月份與當前月份一致,則$bizmonth=業(yè)務日期月份-1。
    • 如果業(yè)務日期的月份與當前月份不一致,則$bizmonth=業(yè)務日期月份。

    $jobid

    任務所屬的業(yè)務流程ID。

    $nodeid

    節(jié)點ID。

    $taskid

    節(jié)點產(chǎn)生的實例ID。


    調(diào)度配置的各板塊:


    配置基礎屬性

    名稱,節(jié)點ID,節(jié)點類型,責任人,描述

    配置調(diào)度參數(shù)

    調(diào)度參數(shù)支持的格式

    配置并使用調(diào)度參數(shù)

    配置時間屬性

    時間屬性配置說明

    實例生成方式:發(fā)布后即時生成實例

    調(diào)度周期:分鐘/小時/天/月調(diào)度

    配置資源屬性

    默認配置為公共調(diào)度資源組。

    配置調(diào)度依賴

    調(diào)度依賴配置

    配置同周期調(diào)度依賴

    配置依賴上一周期(跨周期依賴)

    復雜依賴場景調(diào)度配置原則

    配置節(jié)點上下文

    在節(jié)點上下文配置本節(jié)點輸入?yún)?shù)和本節(jié)點輸出參數(shù)

    輸出參數(shù)的取值分為常量和變量兩種類型

    配置輸入?yún)?shù),在調(diào)度依賴中添加依賴的上游節(jié)點



    更多內(nèi)容請期待下一篇:進階篇。

    證網(wǎng)訊(記者 董添)12月27日,記者從天下秀獲悉,公司旗下星礦科技總經(jīng)理張磊當選中關村云通計算機專業(yè)服務器系統(tǒng)技術創(chuàng)新聯(lián)盟(簡稱“創(chuàng)新聯(lián)盟”)副秘書長。

    據(jù)了解,創(chuàng)新聯(lián)盟成立于2016年,是非盈利公共機構(gòu),其參與運營管理的文創(chuàng)品牌聯(lián)盟鏈由天下秀等多家上市公司及北京市國資委下屬企業(yè)共同成立。作為一條具有公共屬性的可治理開放型聯(lián)盟鏈,文創(chuàng)品牌聯(lián)盟鏈專注于為全國文化創(chuàng)意領域提供底層區(qū)塊鏈基礎設施和應用場景,致力于用技術驅(qū)動數(shù)字經(jīng)濟的新型基礎設施。星礦科技作為國內(nèi)公共區(qū)塊鏈最早的倡導者和數(shù)字經(jīng)濟領域平臺型企業(yè),為文創(chuàng)品牌聯(lián)盟鏈提供架構(gòu)設計和技術維護。

    據(jù)創(chuàng)新聯(lián)盟相關負責人介紹,未來,文創(chuàng)品牌聯(lián)盟鏈將持續(xù)開發(fā)數(shù)字生活類應用、數(shù)字文旅類應用、數(shù)據(jù)資產(chǎn)服務應用、地標產(chǎn)品類應用、數(shù)字產(chǎn)業(yè)園區(qū)應用等內(nèi)容。

網(wǎng)站首頁   |    關于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權(quán)所有