SnowflakeのStream、完全に理解した？

SnowPro（ARA-C01）の勉強をしていまして、使ったことがないStreamを理解しておこうと。
これは自分用勉強メモです。

公式ドキュメント

https://docs.snowflake.com/ja/user-guide/streams-intro

https://docs.snowflake.com/ja/sql-reference/functions/system_stream_has_data

1つ目のリンク、「ストリームの紹介」というページみて、
「フムフム、よくわからん」
となりました。

METADATA＄ACTION、METADATA＄ISUPDATE、METADATA＄ROW_IDという追加の情報がストリームには存在すると。これはSnowPro向けに覚えておく必要がありそう。

:::note info
↑ほんとは半角$ですが、Qiitaが勝手に変な表示にしちゃうので全角＄にあえてしています。
:::

2つ目のリンク「SYSTEM$STREAM_HAS_DATA」にある例のクエリを実際に動かしてみたら完全に理解しました。

```
create table MYTABLE1 (id int);

create table MYTABLE2(id int);

create stream MYSTREAM on table MYTABLE1;

insert into MYTABLE1 values (1);

-- returns true because the stream contains change tracking information
select system$stream_has_data('MYSTREAM');

+----------------------------------------+
| SYSTEM$STREAM_HAS_DATA('MYSTREAM')     |
|----------------------------------------|
| True                                   |
+----------------------------------------+

 -- consume the stream
begin;
insert into MYTABLE2 select id from MYSTREAM;
commit;

-- returns false because the stream was consumed
select system$stream_has_data('MYSTREAM');

+----------------------------------------+
| SYSTEM$STREAM_HAS_DATA('MYSTREAM')     |
|----------------------------------------|
| False                                  |
+----------------------------------------+
```

-- consume the stream
というコメントの部分、<strong>ストリームからselectしてinsertすると消費される</strong>んですね。
⇒完全に理解したのはこの部分です。

なお、SnowSightでテーブルを見ると、Linegeという欄があって、
MYTABLE1⇒MYTABLE2にデータが行ってるよ
という関係性ができていました。
※MYSTREAMからselectしてinsertしたタイミングでこのLineage欄に現れました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/40303e5e-e615-48e0-a17a-8096d5bcddb5.png)

ちょっと疑問が。
MYTABLE2に対するSTREAMを作って、MYTABLE1に入れるようにしたら無限ループ完成しません？？
MYTABLE1からMYTABLE2にストリームで入ったデータを別のストリームが掴んで
MYTABLE2からMYTABLE1に返して、さらにのデータをMYTABLE1からMYTABLE2に・・・。みたいな。

やってみます。
```
create stream MYSTREAM_RE on table MYTABLE2;
insert into MYTABLE2 values (2);
select system$stream_has_data('MYSTREAM_RE');

--SYSTEM$STREAM_HAS_DATA('MYSTREAM_RE')
--TRUE
```
MYTABLE2に対するMYSTREAM_REを作成してMYTABLE2にデータをINSERTしました。
MYSTREAM_REで変更データを保持しています。

```
-- consume the stream
begin;
insert into MYTABLE1 select id from MYSTREAM_RE;
commit;
select system$stream_has_data('MYSTREAM_RE');
select * from MYTABLE1;
---ID
--1
--2
```
MYTABLE1に2というデータが入ってきました。
```
select * from MYTABLE2;
---ID
--1
--2
```
MYTABLE2も同じデータ内容です。
~~無限ループはしないようです。
ひと安心。~~

```
select system$stream_has_data('MYSTREAM');
--SYSTEM$STREAM_HAS_DATA('MYSTREAM')
--TRUE
select system$stream_has_data('MYSTREAM_RE');
--SYSTEM$STREAM_HAS_DATA('MYSTREAM_RE')
--FALSE
```
取り消し線で消したところ、嘘でした。
<strong>ストリームからselectしてinsertすると消費される</strong>
と書いたのにすぐ忘れていました。
まだ「SELECTしてinsertしてない」からストリームが動いてないだけです。
MYTABLE1についているMYSTREAM1、system$stream_has_data('MYSTREAM')がTRUEでした。
SELECTしてINSERTします。

```
begin;
insert into MYTABLE2 select id from MYSTREAM;
commit;

select system$stream_has_data('MYSTREAM');
--SYSTEM$STREAM_HAS_DATA('MYSTREAM')
--FALSE
select * from MYTABLE2;ID
--1
--2
--2
```

2というデータが一行増えてます。

もう一度system$stream_has_dataを実行すると。
```
select system$stream_has_data('MYSTREAM');
--SYSTEM$STREAM_HAS_DATA('MYSTREAM')
--FALSE
select system$stream_has_data('MYSTREAM_RE');
--SYSTEM$STREAM_HAS_DATA('MYSTREAM_RE')
--TRUE
```
SYSTEM$STREAM_HAS_DATAのTRUE/FALSEが逆になりました。

ストリームのselect *をします。
テーブルと同じようにストリーム名を入れたらSELECTできる。
```
select * from MYSTREAM;
--データなし
select * from MYSTREAM_RE;
--ID	METADATA$ACTION	METADATA$ISUPDATE	METADATA$ROW_ID
--2	INSERT	FALSE	4b65189f9994d5410f9df60a2dc6bec58f6726ac
```
MYSTREAMには待ちデータはなく、MYSTREAM_REの方に待ちデータがあります。

これ「2」というデータのラリーが一生続きますね。

ではGUI上のLineageの部分を見てみます。
![スクリーンショット 2025-03-01 121634.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/c683c8d7-818f-4a57-8e43-ef4369a7bd8a.png)
なんか矢印の線が増えたけど、ぱっと見よくわかりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/dfc6b2bd-b793-4fe0-8ed0-0aa11c82e496.png)
矢印をクリックしたら右側に説明がでました。
上の矢印はMYTABLE2⇒MYTABLE1。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3487310/f1ee31ac-4d1b-4831-8c67-0ac8d225f18b.png)
下の矢印はMYTABLE1⇒MYTABLE2。

STREAMの定義としてはどのテーブルに入れるという定義はなく、
STREAMからSELECTしてどのテーブルにINSERT文を発行したか？という実績からこのLineageの図ができてるわけですね。

「STREAMを使った実績からのLineage表示、必要？」って思いました。