JSON_HASH
説明
JSON_HASHはJSONオブジェクトのハッシュ値を計算します。この関数はJSON型のパラメータを受け取り、BIGINTのハッシュ値を返します。
JSONオブジェクトのハッシュ値を計算する際、関数は計算前にJSONオブジェクトのキーをソートし、同一の内容を持つがキーの順序が異なるJSONオブジェクトが同じハッシュ値を生成することを保証します。
構文
JSON_HASH(json_value)
Alias
JSONB_HASH
パラメータ
json_value - ハッシュ値を計算するJSON値。JSON型である必要があります。
Return Value
BIGINT型のハッシュ値を返します。
入力がNULLの場合、関数はNULLを返します。
Usage
JSON標準ではJSONオブジェクトのキーと値のペアは順序付けされていないと規定されているため、異なるシステム間で同じ内容のJSONオブジェクトの一貫した識別を保証するために、JSON_HASH関数はSORT_JSON_OBJECT_KEYS関数を呼び出すのと同様に、ハッシュ値を計算する前にキーと値のペアをソートします。
さらに、JSONオブジェクト内の重複キーについて、Dorisはそれらの存在を許可していますが、ハッシュ計算では最初に出現するキーと値のペアのみを考慮し、これは実際のアプリケーションシナリオにより適合します。
Examples
- 基本的なハッシュ計算
SELECT json_hash(cast('123' as json));
+--------------------------------+
| json_hash(cast('123' as json)) |
+--------------------------------+
| 5279066513252500087 |
+--------------------------------+
- エイリアス機能の検証
SELECT json_hash(cast('123' as json)), jsonb_hash(cast('123' as json));
+--------------------------------+---------------------------------+
| json_hash(cast('123' as json)) | jsonb_hash(cast('123' as json)) |
+--------------------------------+---------------------------------+
| 5279066513252500087 | 5279066513252500087 |
+--------------------------------+---------------------------------+
示されているように、json_hashとjsonb_hash関数は同じ入力に対して同一のハッシュ値を生成しており、これらが等価なエイリアス関数であることが確認されます。
- キーソート検証
SELECT
json_hash(cast('{"a":123, "b":456}' as json)),
json_hash(cast('{"b":456, "a":123}' as json));
+-----------------------------------------------+-----------------------------------------------+
| json_hash(cast('{"a":123, "b":456}' as json)) | json_hash(cast('{"b":456, "a":123}' as json)) |
+-----------------------------------------------+-----------------------------------------------+
| 82454694884268544 | 82454694884268544 |
+-----------------------------------------------+-----------------------------------------------+
json_hash関数は、ハッシュ値を計算する前にキーをソートするため、キーの順序に関係なく同じハッシュ値を生成します。
- 重複キーの処理
SELECT
json_hash(cast('{"a":123}' as json)),
json_hash(cast('{"a":456}' as json)),
json_hash(cast('{"a":123, "a":456}' as json));
+--------------------------------------+--------------------------------------+-----------------------------------------------+
| json_hash(cast('{"a":123}' as json)) | json_hash(cast('{"a":456}' as json)) | json_hash(cast('{"a":123, "a":456}' as json)) |
+--------------------------------------+--------------------------------------+-----------------------------------------------+
| -7416836614234106918 | -3126362109586887012 | -7416836614234106918 |
+--------------------------------------+--------------------------------------+-----------------------------------------------+
JSONオブジェクトに重複するキー({"a":123, "a":456})が含まれている場合、json_hash関数はハッシュ計算において最初のキー・値ペアのみを考慮します。示されているように、重複するキーを持つJSONオブジェクトのハッシュ値は、最初のキー・値ペア{"a":123}のみを含むオブジェクトのハッシュ値と一致します。
- 異なる数値型の処理
SELECT
json_hash(to_json(cast('123' as int))),
json_hash(to_json(cast('123' as tinyint)));
+----------------------------------------+--------------------------------------------+
| json_hash(to_json(cast('123' as int))) | json_hash(to_json(cast('123' as tinyint))) |
+----------------------------------------+--------------------------------------------+
| 7882559133986259892 | 5279066513252500087 |
+----------------------------------------+--------------------------------------------+
同じ数値123がJSONで異なる型(intとtinyint)で保存される場合、異なるハッシュ値が生成されます。これは、DorisのJSON実装が型情報を保持し、ハッシュ計算でこれらの型の違いが考慮されるためです。
- 統一された型のためのnormalize_json_numbers_to_doubleの使用
SELECT
json_hash(normalize_json_numbers_to_double(to_json(cast('123' as int)))),
json_hash(normalize_json_numbers_to_double(to_json(cast('123' as tinyint))));
+--------------------------------------------------------------------------+------------------------------------------------------------------------------+
| json_hash(normalize_json_numbers_to_double(to_json(cast('123' as int)))) | json_hash(normalize_json_numbers_to_double(to_json(cast('123' as tinyint)))) |
+--------------------------------------------------------------------------+------------------------------------------------------------------------------+
| 4028523408277343359 | 4028523408277343359 |
+--------------------------------------------------------------------------+------------------------------------------------------------------------------+
この例では上記の問題を解決する方法を示しています。normalize_json_numbers_to_double関数を使用してまずすべての数値を倍精度浮動小数点型に変換してから、ハッシュ値を計算します。これにより、元の数値型に関係なく一貫したハッシュ値が保証されます。
- NULL値の処理
SELECT json_hash(null);
+-----------------+
| json_hash(null) |
+-----------------+
| NULL |
+-----------------+
注意事項
-
JSON_HASH関数にはエイリアスJSONB_HASHがあり、両方の関数は同一の機能を持ちます。 -
この関数は、
SORT_JSON_OBJECT_KEYS関数を呼び出すのと同様に、ハッシュ値を計算する前にJSONオブジェクトのキーをソートします。 -
JSONオブジェクトで重複するキーについては、関数はハッシュ計算において最初に出現するキーと値のペアのみを考慮します。
-
DorisのJSONは数値を異なる型(int、tinyint、bigint、float、double、decimal)で格納できるため、同じ数値でも異なる型の場合、異なるハッシュ値を生成する可能性があります。一貫性が必要な場合は、
NORMALIZE_JSON_NUMBERS_TO_DOUBLE関数を使用して、ハッシュ値を計算する前にすべての数値を統一された型に変換できます。 -
JSONオブジェクトがテキスト解析を通じて作成される場合(
CASTを使用して文字列をJSONに変換するなど)、Dorisは自動的に適切な数値型を選択して格納するため、通常は数値型の不整合の問題を心配する必要はありません。 -
cast/to_jsonを使用して手動で"123"をJSONオブジェクトに変換するのではなく、テキスト変換(文字列からJSONオブジェクトを解析)を使用する場合、Dorisは"123"をtinyint型のJSONオブジェクトとしてのみ格納し、"123"がint型とtinyint型の両方として格納される状況はありません。