Spanner は、Google SQL データベースと PostgreSQL データベースの両方で、NUMERIC
データ型をサポートしています。
GoogleSQL NUMERIC
GoogleSQL の NUMERIC
は、精度が 38、スケールが 9 で正確な数値を表すことが可能な正確な数値データ型です。このページでは、クライアント ライブラリでの NUMERIC
の表示方法の概要について説明します。
PostgreSQL NUMERIC
PostgreSQL の NUMERIC
型は、最大精度(合計桁数)が 147,455、最大スケール(小数点以下の桁数)が 16,383 の、任意の 10 進数値データ型です。
Spanner DDL では、PostgreSQL NUMERIC
列の精度とスケールを指定できません。ただし、DML ステートメントで数値を固定精度値にキャストできます。次に例を示します。
update t1 set numeric_column = (numeric_column*0.8)::numeric(5,2);
DECIMAL
型は NUMERIC
のエイリアスです。
主キー、外部キー、またはセカンダリ インデックスを指定する場合は、PostgreSQL の NUMERIC
列を使用できません。
各クライアント ライブラリの言語での NUMERIC の表現
NUMERIC
値の忠実度を維持するために、Spanner の各クライアント ライブラリでは、これらの値がクライアント ライブラリ言語の適切なデータ型で格納されます。次の表に、サポートされている各言語で NUMERIC
がマッピングされるデータ型を示します。
言語 | GoogleSQL | PostgreSQL |
---|---|---|
C++ | spanner::Numeric | |
C# | SpannerNumeric | |
Go | big.Rat | カスタム PGNumeric |
Java | BigDecimal | カスタム型。PostgreSQL Java ライブラリの注意事項をご覧ください。 |
Node.js | Big | |
PHP | カスタム Numeric | |
Python | 小数 | カスタム アノテーションを含む Decimal |
Ruby | BigDecimal |
C++、C#、PHP の 3 つのクライアント ライブラリでは、Spanner SQL の NUMERIC
型を表すカスタム型がそれぞれ実装されています。その他のライブラリはすべて既存の型です。
C++ クライアント ライブラリの spanner::Numeric
オブジェクトでは、算術演算がサポートされません。代わりに、含まれている数値を、選択した C++ オブジェクトに変換します。たとえば、数字を文字列として抽出できます。これは、完全な忠実度で、データ損失なしで数値を表します。ただし、たとえば数値が std:int64_t
や double
の範囲内であることが事前にわかっている場合は、その型として値にアクセスできます。
PostgreSQL Java ライブラリの注意事項
Cloud Spanner Java クライアント ライブラリでは、カスタム Value.pgNumeric
型を使用して PostgreSQL NUMERIC の値を格納します。
NUMERIC 列への書き込み
PostgreSQL テーブルの NUMERIC 列への書き込みでは、複数の型がサポートされます。
数値
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23)
整数
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1)
ダブル
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23::float8)
型指定なしのリテラル
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 'NaN')
パラメータ化されたクエリ
パラメータ化されたクエリを使用する場合は、$<index>
でパラメータを指定します。ここで、<index>
は、パラメータの位置を表します。次に、パラメータは p<index>
を使用してバインドする必要があります。たとえば、パラメタがある INSERT INTO MyTable (PgNumericColumn) VALUES ($1)
は p1
です。
現在、Java クライアント ライブラリでは、パラメータ化された値として次の型をサポートしています。
カスタム
Value.pgNumeric
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(Value.pgNumeric("1.23")) .bind("p2") .to(Value.pgNumeric("NaN")) .build()
ダブル
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(1.23D) .bind("p2") .to(Double.NaN) .build()
整数
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1) .build()
Long
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1L) .build()
ミューテーション
ミューテーションを使用すると、数値型の列に次の値を書き込むことができます。
文字列
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to("1.23") .build()
BigDecimal 型の値
BigDecimals
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(new BigDecimal("1.23")) .build()
Int
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1) .build()
Long
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1L) .build()
Value.pgNumeric の呼び出しの結果として得られた値
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(Value.pgNumeric("1.23")) .build()
NUMERIC 列からの取得
ResultSet の数値列に格納された値を取得するには、ResultSet.getString()
か ResultSet.getValue()
を使用します。
文字列
resultSet.getString("PgNumericColumn")
カスタム値
Value pgNumeric = resultSet.getValue("PgNumericColumn"); pgNumeric.getString(); // get underlying value as a String pgNumeric.getNumeric(); // get underlying value as a BigDecimal pgNumeric.getFloat64(); // get underlying value as aDouble
NUMERIC 列の追加
次のサンプルは、Spanner クライアント ライブラリを使用して、NUMERIC
列を Venues
という名前のテーブルに追加する方法を示しています。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
NUMERIC データの更新
次のサンプルでは、Spanner クライアント ライブラリを使用して NUMERIC
データを更新する方法を示します。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
NUMERIC データにクエリを実行する
次のサンプルでは、Spanner クライアント ライブラリを使用して、NUMERIC
データにクエリを実行する方法を示します。
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
NUMERIC
は、Java の BigDecimal 型を使用して、JDBC ドライバでサポートされています。NUMERIC
の使用方法の例については、JDBC を GoogleSQL 言語データベースに接続するのコードサンプルをご覧ください。
クライアント ライブラリまたはドライバの作成時の NUMERIC の処理
NUMERIC
型は、google.protobuf.Value プロトコル内で 10 進表記または科学的記数法で文字列としてエンコードされます。このプロトコルは、読み取りか書き込みかに応じて、ResultSet、PartialResultSet、Mutation のいずれかとしてラップされます。ResultSetMetadata では NUMERIC TypeCode を使用して、対応する値が NUMERIC
として読み取られることを示します。
作成するクライアント ライブラリまたはドライバで NUMERIC を処理するときは、次のガイダンスに注意してください。
ResultSet から
NUMERIC
を読み取るには、次のようにします。TypeCode が
NUMERIC
の場合に、google.protobuf.Value proto から string_value を読み取ります。その文字列を、指定した言語の関連する型に変換します
特定の関連する型の場合、Mutations を使用して
NUMERIC
を書き込むには、文字列表現を google.protobuf.Value プロトコルの string_value として使用します。