Redshiftで任意個数の文字列を扱う
最終的には縦持ちにしちゃえばどんなRDBでも扱えるんだけど、 某MySQLとか某Hadoopとかだと配列で持ってるじゃないですか。 ああいうのをどうやってとりこむか1年くらい考えてたんだけど ついに決定版を思いついた。
扱える個数の上限はあるんだけど、現実的にはほぼ上限を考えなくて済むと思う。
1. 文字列配列をJSONとしてRedshiftに取り込む
=> select * from slog order by 1; id | words ----+--------------- 1 | ["a","b","c"] 2 | ["xxx","yyy"]
2. 連番 1 カラムだけのテーブルを用意する
この連番テーブルのサイズが扱える個数の上限になってしまうので注意
=> select * from sseq order by 1; x --- 1 2 3 4 5
3. ジョインする
不等号でジョインするのがポイント
select slog.id , seq.x as param_id , json_extract_array_element_text(slog.words, seq.x - 1) as word from slog inner join seq on seq.x <= json_array_length(slog.words) order by 1, 2 ;
4. なんと縦持ちになりました!
id | param_id | word ----+----------+------ 1 | 1 | a 1 | 2 | b 1 | 3 | c 2 | 1 | xxx 2 | 2 | yyy
欠点
- 連番テーブルのサイズで扱える個数の上限が決まる
- Redshiftの文字列はかなり上限が短いので個数が多いと入りきらない