【问题标题】:Snapshot of a table daily for 30 days with task and stored procedure30 天内的每日表快照,包含任务和存储过程
【发布时间】:2020-04-07 10:35:41
【问题描述】:

我想在 PST 时区的每天午夜查看表格。这些表非常小,平均每天只有 300 个条目。

我想根据表的 id 跟踪行中的变化,并每天拍摄它们的状态快照,其中每个新表视图都将具有“日期”状态。

挑战在于原始表格正在增长,因此每个新的“快照”都会有不同的大小。

这是我的数据示例:

第 1 天

Id Article Title                   Genre          views  date
 1,  "I Know Why the Caged Bird Sings",  10,     01-26-2019
 2,  "In the Cold",    "Non-Fiction",      20,     01-26-2019

第 2 天

Id Article Title                   Genre          views  date  
1,  "I Know Why the Caged Bird Sings", "Non-Fiction",  20,     02-27-2019
2,  "In the Cold",    "Non-Fiction",      40,     02-27-2019
3,  "Bury My Heart At Wounded Knee",       "Non-Fiction",         100,    02-27-2019

我想创建一个存储过程来复制当前表的状态。但是不建议在存储过程中创建表,所以我正在尝试创建一个管理表创建和存储过程调用的任务:

USE WAREHOUSE "TEST";
CREATE DATABASE "Snapshots"; 
USE DATABASE "Snapshots";


Create or Replace Table ArticleLibrary (id int, Title string, Genre string, Viewed number, date_captured timestamp );

INSERT INTO ArticleLibrary Values
 (1,  'The man who walked the moon',   'Non-Fiction',  10, CURRENT_DATE() ),
  (2,  'The girl who went to Vegas',    'Fiction',      20 , CURRENT_DATE())
;

SELECT * FROM ArticleLibrary;

//CREATE Stored Procedure
create procedure Capture_daily()
   Returns string
    LANGUAGE JAVASCRIPT
  AS
  $$

  var rs = snowflake.execute({sqlText: "})
  var rs = snowflake.execute( {sqlText: "COPY INTO "ARTICLELIBRARY"+CURRENT_DATE() * FROM ArticleLibrary; "} ); );

  return 'success';

  $$
  ;

CREATE OR REPLACE TASK IF NOT EXISTS Snapshot_ArticleLibrary_Task
  WAREHOUSE = 'TEST'
  SCHEDULE = '{ 1440 MINUTE | USING CRON 0 America/Los_Angeles }' 
AS
CREATE TABLE "ARTICLELIBRARY"+"CURRENT_DATE()";
CALL Capture_daily(); 

//Run tomorrow
INSERT INTO ArticleLibrary Values
 (3,  'The Best Burger in Town', 'News', 100, CURRENT_DATE());

我需要一些帮助来改进我设置的存储过程和任务,我不确定如何在任务结束时调用多个 sql 语句。

我愿意就如何更好地实现这一目标提出建议,因为这只是少量数据,只是一个小规模展示计算成本的实验。我还在考虑在一个大表中使用带有窗口框架的窗口函数,该表插入来自每个新一天的数据,其中日期是状态,然后 id 将不是唯一的。

【问题讨论】:

  • 你不能用时间旅行来做这个吗?
  • 时间旅行的时间可能不够长。

标签: snowflake-cloud-data-platform


【解决方案1】:

我建议为此利用 Snowflake 的零拷贝克隆功能。您可以每天使用一个简单的命令创建一个克隆,这不会花费任何时间,而且如果基础数据每天都没有完全改变,那么您也不会使用任何额外的存储空间。

https://docs.snowflake.net/manuals/sql-reference/sql/create-clone.html

您仍然需要一个 SP 来根据日期动态创建表名,并且您可以从 TASK 中执行该 SP。

【讨论】:

  • 值得一提的是,从明年开始,零拷贝克隆的大量使用将产生一些潜在成本。 snowflake.com/blog/…
  • 您为什么认为服务计费与零拷贝克隆有关?这不是服务级别的功能,不应影响计费。零拷贝克隆只是为相同的微分区创建一个新的元信息……但查询该信息不会影响客户的账单。
  • 链接上不清楚什么会影响服务层的成本。据我了解,服务层确实启用了零拷贝克隆,因此假设多次克隆表并在元数据层中有许多指针会增加您对它的使用率并不是一件容易的事。
【解决方案2】:

由于您谈论的是每日快照和如此少量的数据,因此我会将每天的快照插入到单个表中,并将 current_date() 作为一个名为“snapshot_id”的新列。

您可以在此表顶部查看显示最新日期的视图,甚至可以将日期作为参数并返回任何一天的结果的 UDF。这张表会非常快,因为它会自然地被“snapshot_id”列聚集在一起,你将把所有的历史记录集中在一个漂亮而干净的地方。

我过去曾这样做过,因为我们的源表有数百万条记录,而您可以通过这种方法走得更远。

【讨论】:

    【解决方案3】:

    对于问题:我不知道如何在任务结束时调用多个sql语句。

    其中一种方法是将多个 sql 命令按所需顺序嵌入到存储过程中,并通过任务调用此存储过程。

    create or replace procedure capture_daily()
    returns string
    language javascript
    as
    $$
    
    var sql_command1 = snowflake.createStatement({ sqlText:`Create or Replace Table 
    "ARTICLELIBRARY".....`});
    
    var sql_command2 = snowflake.createStatement({ sqlText:'COPY INTO 
    "ARTICLELIBRARY" ...`});
    
    var sql_command3 = snowflake.createStatement({ sqlText:"Any Other DML 
    Command OR CALL sp_name"});
     
    try 
    { 
    sql_command1.execute(); 
    sql_command2.execute(); 
    sql_command3.execute(); 
    
    return "Succeeded."; 
    } 
    catch (err) 
    { 
    
    return "Failed: " + err;
    } 
    $$
    ;
    
     
    
    CREATE OR REPLACE TASK IF NOT EXISTS Snapshot_ArticleLibrary_Task
    WAREHOUSE = 'TEST'
    SCHEDULE = '{ 1440 MINUTE | USING CRON 0 America/Los_Angeles }' 
    AS
    CALL Capture_daily();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-04
      • 2018-02-19
      • 1970-01-01
      • 2020-07-08
      • 2014-11-02
      • 2020-06-29
      • 1970-01-01
      相关资源
      最近更新 更多