本节提供有关 MySQL 数据类型在 NDBCLUSTER 表列中的表示方式以及如何在 NDB API 应用程序中访问这些值的信息。
数字数据类型。
MySQL TINYINT
、
SMALLINT
、
INT
和
BIGINT
数据类型映射到
NDB
与其对应的 MySQL 具有相同名称和存储要求的类型。
MySQLFLOAT
和
DOUBLE
数据类型映射到
NDB
具有相同名称和存储要求的类型。
用于字符数据的数据类型。
MySQL列所需的存储空间
CHAR
由最大字符数和列的字符集决定。对于大多数(但不是全部)字符集,每个字符占用一个字节的存储空间。使用 时utf8
,每个字符需要三个字节;utfmb4
每个字符最多使用四个字节。Maxlen
通过检查的输出中的列,您可以找到给定字符集中每个字符所需的最大字节数SHOW CHARACTER SET
。
NDB
VARCHAR
列值映射到 MySQL VARCHAR
,除了前两个字节保留用于字符串
的NDB
VARCHAR
长度。像此处所示的实用程序函数可以使
VARCHAR
值准备好在 NDB API 应用程序中使用:
void make_ndb_varchar(char *buffer, char *str)
{
int len = strlen(str);
int hlen = (len > 255) ? 2 : 1;
buffer[0] = len & 0xff;
if( len > 255 )
buffer[1] = (len / 256);
strcpy(buffer+hlen, str);
}
您可以使用此功能,如下所示:
char myVal[128+1]; // Size of myVal (+1 for length)
...
make_ndb_varchar(myVal, "NDB is way cool!!");
myOperation->setValue("myVal", myVal);
有关使用 NDB API 向表写入和读取
值
的完整示例程序,
请参阅第 2.5.12 节,“NDB API 简单数组示例” 。VARCHAR
VARBINARY
VARCHAR
MySQL 对or
列
的存储要求
VARBINARY
取决于该列是存储在内存中还是磁盘上:
对于内存中的列,
NDB
存储引擎支持具有 4 字节对齐的可变宽度列。这意味着(例如)'abcde'
存储在VARCHAR(50)
使用字符集的列中的 字符串latin1
需要 12 个字节——在这种情况下,2 个字节乘以 5 个字符是 10,四舍五入到下一个 4 的偶数倍数得到 12。对于磁盘数据列,
VARCHAR
并VARBINARY
存储为固定宽度的列。这意味着这些类型中的每一种都需要与CHAR
相同大小的相同的存储量。
在本指南中,我们将任何 MySQL
TEXT
或
BLOB
类型的列称为“ blob 列”,并将其类型称为“ blob ”。NDB 7.5 及更高版本还将 MySQL
JSON
列视为 blob 列。
NDB ClusterBLOB
或TEXT
列中的每一行都由两个独立的部分组成。其中之一是固定大小(256 字节),实际上存储在原始表中。另一个包含超过 256 字节的任何数据,这些数据存储在隐藏的 blob 表中,其行始终为 2000 字节长。这意味着or
列
中的size
字节
记录需要TEXT
BLOB
256 字节,如果
size
<= 256256 + 2000 * ((
否则字节size
– 256) \ 2000) + 1)
时间数据类型。
NDB API 中时间类型的存储取决于是使用 MySQL 的不带小数秒的“旧”类型还是使用带小数秒支持的“新”类型。在 MySQL 5.6 以及基于它的 NDB Cluster 版本(即 NDB 7.3 和 NDB 7.4)中引入了对小数秒的支持。这些版本默认使用新的临时类型,但可以通过启动mysqld来使用旧的
--create-old-temporals=ON
. NDB 7.5及之后的版本——也就是那些基于MySQL 5.7及之后的NDB Cluster版本——可以使用旧的时间类型读写数据,但是不能创建使用旧类型的表。有关
MySQL 服务器中这些更改的更多信息,
请参阅时间值中的小数秒。
因为在未来的版本中预计会删除对旧时态类型的支持,所以我们鼓励您将使用旧时态类型的任何表迁移到这些类型的新版本。您可以通过
ALTER TABLE
使用旧时间对任何表执行复制操作,或通过备份和恢复任何此类表来实现这一点。
您可以通过检查NDB Cluster 发行版提供的ndb_desc实用程序
的输出来查看给定表是使用旧的还是新的时间类型。考虑在名为 的数据库中创建一个表test
,使用以下语句,在没有选项
的情况下启动mysqld :--create-old-temporals
CREATE TABLE t1 (
c1 DATETIME,
c2 DATE,
c3 TIME,
c4 TIMESTAMP,
c5 YEAR) ENGINE=NDB;
ndb_desc输出
的相关部分(Attributes
块)如下所示:
$> ndb_desc -dtest t1
...
-- Attributes --
c1 Datetime2(0) NULL AT=FIXED ST=MEMORY
c2 Date NULL AT=FIXED ST=MEMORY
c3 Time2(0) NULL AT=FIXED ST=MEMORY
c4 Timestamp2(0) NOT NULL AT=FIXED ST=MEMORY DEFAULT 0
c5 Year NULL AT=FIXED ST=MEMORY
新的 MySQL 时间类型的名称带有后缀
2
(例如,Datetime2
),以将它们与这些类型的旧版本区分开来。假设我们重新启动mysqld,
--create-old-temporals=ON
然后使用以下语句t2
在test
数据库中创建一个表:
CREATE TABLE t2 (
c1 DATETIME,
c2 DATE,
c3 TIME,
c4 TIMESTAMP,
c5 YEAR) ENGINE=NDB;
如图所示,在此表上
执行ndb_descAttributes
的输出包括此处显示的块:
$> ndb_desc -dtest t2
...
-- Attributes --
c1 Datetime NULL AT=FIXED ST=MEMORY
c2 Date NULL AT=FIXED ST=MEMORY
c3 Time NULL AT=FIXED ST=MEMORY
c4 Timestamp NOT NULL AT=FIXED ST=MEMORY DEFAULT 0
c5 Year NULL AT=FIXED ST=MEMORY
受影响的 MySQL 类型是
TIME
、
DATETIME
和
TIMESTAMP
。这些类型的“新”
版本在 NDB API 中分别反映为
Time2
、Datetime2
和
Timestamp2
,每个版本都支持精度高达 6 位的小数秒。新变体使用整数值的大端编码,然后对其进行处理以确定每个时间类型的组件。
对于每种类型的小数秒部分,精度会影响所需的字节数,如下表所示:
表 2.1 NDB API 新时间类型的精度
精确 | 所需字节 | 范围 |
---|---|---|
0 | 0 | — |
1个 | 1个 | 0-9 |
2个 | 1个 | 0-99 |
3个 | 2个 | 0-999 |
4个 | 2个 | 0-9999 |
5个 | 3个 | 0-99999 |
6个 | 3个 | 0-999999 |
每个新时间类型的小数部分都以大端格式存储——也就是说,最高位字节在最低地址——使用必要的字节数。
这些类型的新旧版本的二进制布局在接下来的几段中描述。
Time
:此类型的“旧”版本存储为以小端格式存储的 24 位有符号int
值(最低位地址中的最低位字节)。根据以下公式,字节 0(位 0-7)对应小时,字节 2(位 8-15)对应分钟,字节 2(位 16-23)对应秒:
value = 10000 * hour
+ 100 * minute
+ second
第 23 位作为符号位;如果该位被设置,时间值被认为是负的。
Time2
:这是 NDB 7.3 和 7.4(MySQL 5.6)中添加的“新”
TIME
类型,存储为 3 字节 big-endian 编码值加上小数部分的 0 到 3 字节。整数部分编码如下表所示:
除此之外的任何小数字节都按前面所述进行处理。
Date
:MySQL
DATE
类型的表示在 NDB 版本中保持不变,并使用以小端顺序存储的 3 字节无符号整数。编码如下所示:
Datetime
:“旧” MySQL
DATETIME
类型由以主机字节顺序存储的 64 位无符号值表示,使用以下公式编码:
value = second
+ minute * 102
+ hour * 104
+ day * 106
+ month * 108
+ year * 1010
DateTime2
:“ new ”
DATETIME
被编码为 5 字节 big-endian,带有 0 到 3 字节的可选小数部分,小数部分的处理如前所述。高 5 字节的编码如下所示:
这些YearMonth
位被编码为
Year = YearMonth / 13
和Month =
YearMonth % 13
。
Timestamp
:此类型的“旧”版本使用 32 位无符号值表示自 Unix 纪元以来经过的秒数,以主机字节顺序存储。
Timestamp2
:这是
TIMESTAMP
在 NDB 7.3 和 7.4 (MySQL 5.6) 中实现的版本,并使用 4 个字节和 big-endian eoncoding 整数部分(无符号)。可选的 3 字节小数部分按照本节前面的说明进行编码。
附加信息。
有关 NDB API 中表示的 uding 数据类型的更多信息和示例,请参见
ndb/src/common/util/NdbSqlUtil.cpp
。此外,请参阅第 2.5.14 节,“Timestamp2 示例”,它提供了一个使用Timestamp2
数据类型的简单 NDB API 应用程序的示例。