如何限制重复记录插入到雪花表中

Nee*_*dav 8 snowflake-cloud-data-platform

我在雪花中使用主键创建了下表,每当我尝试将数据插入该表时,它也允许重复记录。如何限制重复的id?

create table tab11(id int primary key not null,grade varchar(10));

insert into tab11 values(1,'A');
insert into tab11 values(1,'B');

select * from tab11;
Run Code Online (Sandbox Code Playgroud)

输出:插入重复记录。

ID  GRADE
1   A
1   B
Run Code Online (Sandbox Code Playgroud)

Sim*_*onD 9

Snowflake 允许您将列标识为主键,但它不会强制它们的唯一性。从这里的文档:

Snowflake 支持定义和维护约束,但不强制执行它们,除了始终强制执行的 NOT NULL 约束。

Snowflake 中的主键纯粹是为了提供信息。我不是来自 Snowflake,但我认为在主键中强制执行唯一性并不真正符合 Snowflake 在幕后存储数据的方式,并且可能会影响插入速度。


Gre*_*lik 5

您可能需要考虑使用 merge 语句来处理具有重复 PK 的行到达时发生的情况:

create table tab1(id int primary key not null, grade varchar(10));

insert into tab1 values(1, 'A');

-- Try merging values 1, and 'B': Nothing will be added
merge into tab1 using 
    (select * from (values (1, 'B')) x(id, grade)) tab2 
  on tab1.id = tab2.id
    when not matched then insert (id, grade)
                          values (tab2.id, tab2.grade);

select * from tab1;

-- Try merging values 2, and 'B': New row added
merge into tab1 using 
    (select * from (values (2, 'B')) x(id, grade)) tab2 
  on tab1.id = tab2.id
    when not matched then insert (id, grade)
                          values (tab2.id, tab2.grade);

select * from tab1;

-- If instead of ignoring dupes, we want to update:
merge into tab1 using 
    (select * from (values (1, 'F'), (2, 'F')) x(id, grade)) tab2 
  on tab1.id = tab2.id
    when matched then update set tab1.grade = tab2.grade
    when not matched then insert (id, grade)
                          values (tab2.id, tab2.grade);

select * from tab1;
Run Code Online (Sandbox Code Playgroud)

对于更复杂的合并,您可能需要使用 Snowflake 流(更改数据捕获表)进行研究。除了文档之外,我还创建了一个 SQL 脚本演练,介绍如何使用流来保持暂存表和生产表同步:

https://snowflake.pavlik.us/index.php/2020/01/12/snowflake-streams-made-simple