ClickHouse 2021年1~2月新機能
Release notes からピックアップして新機能を紹介します。
リリースノート全体はこちらで見れます。
https://github.com/ClickHouse/ClickHouse/blob/master/CHANGELOG.md
v21.1.2.15-stable 2021-01-18 で追加
REPLACE TABLE / CREATE OR REPLACE TABLE
REPLACE TABLE / CREATE OR REPLACE TABLE 文で、atomicにテーブルを入れ替えられるようになりました。
今までは
CREATE TABLE myNewTable AS myOldTable;
INSERT INTO myNewTable SELECT * FROM myOldTable WHERE CounterID <12345;
DROP TABLE myOldTable;
RENAME TABLE myNewTable TO myOldTable;
でしたが、以下のように書けるようになりました。
REPLACE TABLE myOldTable SELECT * FROM myOldTable WHERE CounterID <12345;
ただし、データベースの種別がAtomicでないと使えません。
最近のバージョンで新規に作成したデータベースは、デフォルトでAtomicになりますが、以前のバージョンで作ったものは Ordinary かもしれません。
以下のSQLで確認できます。
SELECT * FROM system.databases
Ordinary から Atomic に簡単に変換する方法は用意されていないようなので、移行したい場合は新しくデータベースを作り、テーブルを移す必要がありそうです。
accurateCastOrNull関数
ClickHouseでは、性能のために、デフォルトでCASTしたときにオーバーフロー等が考慮されません。
範囲内か判定したい場合にこの新しい関数が使えます。
SELECT accurateCastOrNull(-1, 'UInt8')
┌─accurateCastOrNull(-1, 'UInt8')─┐
│ ᴺᵁᴸᴸ │
└─────────────────────────────────┘
SELECT cast(-1, 'UInt8')
┌─cast(-1, 'UInt8')─┐
│ 255 │
└───────────────────┘
toModifiedJulianDay / fromModifiedJulianDay / toModifiedJulianDayOrNull / fromModifiedJulianDayOrNull関数
ClickHouseの日付は、1970年以降の範囲しか扱えません。
この関数で文字列での日付と Modified Julian Day number を相互変換することができるので、0000~9999年の範囲で日数計算ができるようになります。
SELECT fromModifiedJulianDay(toModifiedJulianDay('1950-01-01') + 20000)
┌─fromModifiedJulianDay(plus(toModifiedJulianDay('1950-01-01'), 20000))─┐
│ 2004-10-04 │
└───────────────────────────────────────────────────────────────────────┘
こちらは当社開発者からプルリクエストした関数になります。
clickhouse-client の queries-file オプション
SQLを記入したファイルを指定して実行できるようになりました。
Map型
新しくMap型が追加されました。
まだexperimental扱いなので、設定を変えないと利用できません。
動的に変わる項目を管理する場合に便利に使えると思います。
SET allow_experimental_map_type = 1
Ok.
CREATE TABLE table_map
(
`user` Map(String, String)
)
ENGINE = MergeTree
ORDER BY tuple()
Ok.
INSERT INTO table_map
VALUES ({'name': 'mikage'}), ({'name': 'tomomi', 'email':'tomomi@example.com'});
Ok.
SELECT * FROM table_map
┌─user───────────────────────────────────────────┐
│ {'name':'mikage'} │
│ {'name':'tomomi','email':'tomomi@example.com'} │
└────────────────────────────────────────────────┘
SELECT
user['name'],
user['email']
FROM table_map
┌─arrayElement(user, 'name')─┬─arrayElement(user, 'email')─┐
│ mikage │ │
│ tomomi │ tomomi@example.com │
└────────────────────────────┴─────────────────────────────┘
v21.2.2.8-stable 2021-02-07 で追加
PostgreSQLとの連携
mysqlには直接接続できますが、同じようにpostgresqlにも接続できるようになりました。
使い方はMySQLと同様です。
(記事作成時点では、まだドキュメントには書かれてないようです・・・)
SELECT * ROM mysql('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']);
SELECT * FROM postgresql('host:port', 'database', 'table', 'user', 'password');