Spanner 在 GoogleSQL 和NUMERIC
PostgreSQL 数据库。
GoogleSQL NUMERIC
GoogleSQL NUMERIC
是
能够使用
精度为 38,标度为 9。本页面简要介绍了 NUMERIC
在客户端库中的表示方式。
PostgreSQL NUMERIC
PostgreSQL NUMERIC
类型是任意小数精度数值数据类型,最大精度(总位数)为 147,455,最大标度(小数点右侧的位数)为 16,383。
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 | 大 | |
PHP | 自定义数值 | |
Python | 小数 | 具有自定义注释的小数 |
Ruby | BigDecimal |
三个客户端库(C++、C# 和 PHP)都实现了自定义类型,
代表 Spanner SQL 的 NUMERIC
类型。所有其他库使用现有类型。
C++ 客户端库 spanner::Numeric
对象不支持算术运算。而是将包含的数字转换为所选的 C++ 对象。例如,您可以将数字串提取为字符串,该字符串将完全保真地表示该数字,且不会丢失数据。但是,如果您事先知道该数字适合(例如,在 std:int64_t
或 double
的范围内的值),那么您可以访问该类型的值。
PostgreSQL Java 库说明
Spanner Java 客户端库使用自定义 Value.pgNumeric
类型
存储 PostgreSQL NUMERIC 值。
写入 NUMERIC 列
在 PostgreSQL 表中写入 NUMERIC 列时,系统支持多种类型。
Numerics
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23)
Integers
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1)
Doubles
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 1.23::float8)
无类型字面量
INSERT INTO Table (id, PgNumericColumn) VALUES (1, 'NaN')
参数化查询
使用参数化查询时,请使用 $<index>
指定参数,其中 <index>
表示参数位置。然后,应使用 p<index>
来绑定该参数。例如,参数为 p1
的 INSERT INTO MyTable (PgNumericColumn) VALUES ($1)
。
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()
Doubles
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1), ($2)") .bind("p1") .to(1.23D) .bind("p2") .to(Double.NaN) .build()
Integers
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1) .build()
Longs
Statement .newBuilder("INSERT INTO MyTable (PgNumericColumn) VALUES ($1)") .bind("p1") .to(1L) .build()
Mutations
使用 Mutations 时,可以将以下值写入数值类型的列:
字符串
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to("1.23") .build()
BigDecimal 类型的值
BigDecimals
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(new BigDecimal("1.23")) .build()
Ints
Mutation .newInsertBuilder("MyTable") .set("PgNumericColumn") .to(1) .build()
Longs
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 列
以下示例展示了如何将 NUMERIC
列添加到名为
Venues
(使用 Spanner 客户端库)。
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
使用 Java 的 Spanner JDBC 驱动程序支持 NUMERIC
BigDecimal 类型。如需查看有关如何创建
NUMERIC
,请参阅
将 JDBC 连接到 GoogleSQL 方言数据库。
创建客户端库或驱动程序时处理 NUMERIC
NUMERIC
类型在 google.protobuf.Value proto 中采用十进制或科学计数法编码为字符串。此 proto 会封装为 ResultSet、PartialResultSet 或 Mutation,具体取决于它是正在被读取还是被写入。ResultSetMetadata 将使用 NUMERIC TypeCode 来指示应将对应的值读取为 NUMERIC
。
在您创建的客户端库或驱动程序中使用 NUMERIC 时,请注意以下指南。
要从 ResultSet 中读取
NUMERIC
,请运行以下命令:当 TypeCode 为
NUMERIC
时,从 google.protobuf.Value proto 读取 string_value将该字符串转换为指定语言的相关类型
如要使用 Mutation 写入
NUMERIC
,请在提供相关类型的情况下,将字符串表示形式用作 google.protobuf.Value proto 中的 string_value。