カテゴリ:

ハッシュ関数

HASH

符号付き64ビットのハッシュ値を返します。HASH は、 NULL 入力に対しても NULLを返しません。

HASH 関数の可能な用途は次のとおりです。

  • 歪んだデータ値を、よりランダムまたはより均等に分布する可能性が高い値に変換します。

    例えば、非常に歪んだ値のグループをハッシュし、ランダムに分布または均等に分布する可能性が高い値のセットを生成できます。

  • バケットにデータを入れます。ハッシュは歪んだデータ値をより均等に分布した値に変換できるため、ハッシュを使用して歪んだ値を取得し、ほぼ均等なサイズのバケットを作成できます。

    必要な個別のバケットの数を取得するには、ハッシュだけでは不十分な場合、ハッシュを ROUND または WIDTH_BUCKET 関数と組み合わせることができます。

注釈

HASH は、任意の型の可変数に対する入力式を受け入れ、符号付きの値を返す独自の関数です。暗号化ハッシュ関数 ではない ため、そのまま使用しないでください。

暗号化ハッシュ関数には、この関数にはない次のようなプロパティがあります。

  • 値の暗号ハッシュを元の値を見つけるために逆にはできません。

  • 値を指定すると、同じ暗号化ハッシュを持つ別の値を見つけることはできません。

暗号化のために、 SHA ファミリーの関数( 文字列とバイナリ関数 内)を使用します。

こちらもご参照ください:

HASH_AGG

構文

HASH( <expr> [ , <expr2> ... ] )

HASH(*)
Copy

引数

exprN

式は、Snowflakeデータ型の一般的な式にすることができます。

戻り値

符号付き64ビット値を NUMBER(19、0)として返します。

HASH は、 NULL 入力に対しても NULLを返しません。

使用上の注意

  • HASH は、以下を保証するという意味で 安定 しています。

    • それぞれのタイプの精度および/またはスケールが異なる場合でも、等しく比較するタイプ NUMBER の2つの値は同じハッシュ値にハッシュされます。

    • 精度を損なうことなく NUMBER(38、0)に変換できるタイプ FLOAT の2つの値は、同じ値にハッシュされます。たとえば、次はすべて同じハッシュ値を返します。

      • HASH(10::NUMBER(38,0))

      • HASH(10::NUMBER(5,3))

      • HASH(10::FLOAT)

    • タイムスタンプが異なるタイムゾーンからのものであっても、等しく比較する型 TIMESTAMP_TZ の2つの値は同じハッシュ値にハッシュされます。

    • この保証は、 VARIANT 列内の NUMBER、 FLOAT、および TIMESTAMP_TZ 値にも適用されます。

    • この保証は、型の間に暗黙的な変換が存在する場合でも、型の他の組み合わせには 適用されません 。たとえば、圧倒的な確率で、暗黙的な変換後 10 = '10' であっても、以下は同じハッシュ値を返しません。

      • HASH(10)

      • HASH('10')

  • HASH(*) は、行のすべての列に基づいて単一のハッシュ値を作成することを意味します。

  • HASH() を使用して一意のキーを作成しないでください。HASH() には64ビットの有限解像度があり、2^64を超える値が入力された場合(例: 2^64行を超えるテーブルの場合)は、一意でない値を返すことが保証されます。実際には、入力が2^32行(約4億行)以上のオーダーである場合、関数は少なくとも1つの重複値を返す可能性があります。

照合の詳細

No impact.

  • 同一だが照合仕様が異なる2つの文字列は、同じハッシュ値を持ちます。つまり、照合仕様ではなく文字列のみがハッシュ値に影響します。

  • 異なる2つの文字列が照合では同等に比較され、異なるハッシュ値を持つ場合があります。例えば、句読点に依存しない照合を使用した同一の2つの文字列のハッシュ値に影響するのは照合仕様ではなく文字列のみであるため、通常は異なるハッシュ値になります。

SELECT HASH(SEQ8()) FROM TABLE(GENERATOR(rowCount=>10));

----------------------+
     HASH(SEQ8())     |
----------------------+
 -6076851061503311999 |
 -4730168494964875235 |
 -3690131753453205264 |
 -7287585996956442977 |
 -1285360004004520191 |
 4801857165282451853  |
 -2112898194861233169 |
 1885958945512144850  |
 -3994946021335987898 |
 -3559031545629922466 |
----------------------+
Copy
SELECT HASH(10), HASH(10::number(38,0)), HASH(10::number(5,3)), HASH(10::float);

---------------------+------------------------+-----------------------+---------------------+
      HASH(10)       | HASH(10::NUMBER(38,0)) | HASH(10::NUMBER(5,3)) |   HASH(10::FLOAT)   |
---------------------+------------------------+-----------------------+---------------------+
 1599627706822963068 | 1599627706822963068    | 1599627706822963068   | 1599627706822963068 |
---------------------+------------------------+-----------------------+---------------------+
Copy
SELECT HASH(10), HASH('10');

---------------------+---------------------+
      HASH(10)       |     HASH('10')      |
---------------------+---------------------+
 1599627706822963068 | 3622494980440108984 |
---------------------+---------------------+
Copy
SELECT HASH(null), HASH(null, null), HASH(null, null, null);

---------------------+--------------------+------------------------+
     HASH(NULL)      |  HASH(NULL, NULL)  | HASH(NULL, NULL, NULL) |
---------------------+--------------------+------------------------+
 8817975702393619368 | 953963258351104160 | 2941948363845684412    |
---------------------+--------------------+------------------------+
Copy

以下の例は、テーブルに複数の列が含まれている場合でも、 HASH(*) は行ごとに1つの値を返すことを示しています。

CREATE TABLE orders (order_ID INTEGER, customer_ID INTEGER, order_date ...);

...

SELECT HASH(*) FROM orders LIMIT 10;

----------------------+
       HASH(*)        |
----------------------+
 -3527903796973745449 |
 6296330861892871310  |
 6918165900200317484  |
 -2762842444336053314 |
 -2340602249668223387 |
 5248970923485160358  |
 -5807737826218607124 |
 428973568495579456   |
 2583438210124219420  |
 4041917286051184231  |
----------------------+
Copy