本節提供有關 MySQL 資料類型在 NDBCLUSTER 資料表欄位中的表示方式,以及如何在 NDB API 應用程式中存取這些值的方式的資訊。
數值資料類型。 MySQL TINYINT
、SMALLINT
、INT
和 BIGINT
資料類型會對應至與其 MySQL 對應項目具有相同名稱和儲存需求的 NDB
類型。
MySQL FLOAT
和 DOUBLE
資料類型會對應至具有相同名稱和儲存需求的 NDB
類型。
用於字元資料的資料類型。 MySQL CHAR
資料行所需的儲存空間取決於字元的最大數量和資料行的字元集。對於大多數(但不是全部)字元集,每個字元佔用一個位元組的儲存空間。使用 utf8
時,每個字元需要三個位元組;utfmb4
則每個字元最多使用四個位元組。您可以透過檢查 SHOW CHARACTER SET
的輸出中的 Maxlen
資料行,找到指定字元集中每個字元所需的最大位元組數。
一個 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);
請參閱 第 2.5.12 節「NDB API 簡單陣列範例」,以取得一個完整的範例程式,該程式使用 NDB API 將 VARCHAR
和 VARBINARY
值寫入和讀取至資料表。
MySQL VARCHAR
或 VARBINARY
資料行的儲存需求取決於該資料行是儲存在記憶體中還是磁碟上
對於記憶體中的資料行,
NDB
儲存引擎支援具有 4 位元組對齊的可變寬度資料行。這表示(例如)使用latin1
字元集儲存在VARCHAR(50)
資料行中的字串'abcde'
需要 12 個位元組—在此案例中,2 個位元組乘以 5 個字元為 10,向上捨入到下一個 4 的偶數倍得到 12。對於磁碟資料資料行,
VARCHAR
和VARBINARY
會儲存為固定寬度的資料行。這表示這些類型中的每一種都需要與相同大小的CHAR
相同的儲存空間。
我們在本指南中將 MySQL 的任何 TEXT
或 BLOB
類型的資料行稱為「blob 資料行」,並將其類型稱為「blob」。NDB 7.5 和更新版本也會將 MySQL JSON
資料行視為 blob 資料行。
NDB Cluster 中 BLOB
或 TEXT
資料行中的每一列都由兩個獨立的部分組成。其中一個具有固定大小(256 個位元組),且實際上儲存在原始資料表中。另一個則包含超過 256 個位元組的任何資料,這些資料儲存在隱藏的 blobs 資料表中,其列始終為 2000 個位元組長。這表示 TEXT
或 BLOB
資料行中,大小為 size
個位元組的記錄需要
256 個位元組,如果
size
<= 256256 + 2000 * ((
個位元組,否則size
– 256) \ 2000) + 1)
時間資料類型。NDB API 中時間類型的儲存方式取決於是否使用 MySQL 的「舊」類型(不含小數秒)或「新」類型(支援小數秒)。MySQL 5.6 以及基於此版本的 NDB Cluster 版本(即 NDB 7.3 和 NDB 7.4)中引入了對小數秒的支援。這些以及更高版本的 MySQL Server 和 NDB Cluster 預設使用新的時間類型,可以讀寫使用舊時間類型的資料,但無法建立使用舊類型的資料表。詳情請參閱時間值中的小數秒。
由於預計在未來版本中將移除對舊時間類型的支援,建議您將任何使用舊時間類型的資料表遷移至這些類型的新版本。您可以對任何使用舊時間類型的資料表執行複製的ALTER TABLE
作業,或備份並還原任何此類資料表來完成此操作。
您可以透過檢查 NDB Cluster 發行版提供的 ndb_desc 公用程式的輸出,查看給定的資料表是否使用舊或新的時間類型。考慮在名為 test
的資料庫中建立的資料表,使用以下語句,在啟動時沒有使用 --create-old-temporals
選項的 mysqld 上建立:
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
),以區分它們與這些類型的舊版本。假設我們使用 --create-old-temporals=ON
重新啟動 mysqld,然後使用以下語句在 test
資料庫中建立資料表 t2
:
CREATE TABLE t2 (
c1 DATETIME,
c2 DATE,
c3 TIME,
c4 TIMESTAMP,
c5 YEAR) ENGINE=NDB;
在此資料表上執行 ndb_desc 的輸出(如所示)包含此處所示的 Attributes
區塊:
$> 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.2 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)對應於小時,位元組 1(位元 8-15)對應於分鐘,位元組 2(位元 16-23)對應於秒:
value = 10000 * hour
+ 100 * minute
+ second
位元 23 用作符號位;如果設定了此位元,則時間值被視為負值。
Time2
:這是「新」的 TIME
類型,並儲存為 3 位元組的大端位元組編碼值,加上小數部分的 0 到 3 個位元組。整數部分的編碼如下表所示:
除此之外的任何小數位元組都將按照先前的描述進行處理。
Date
:MySQL DATE
類型的表示在 NDB 版本中沒有改變,並使用以小端位元組順序儲存的 3 位元組無符號整數。編碼如下所示:
Datetime
:「舊」的 MySQL DATETIME
類型由以主機位元組順序儲存的 64 位元無符號值表示,並使用以下公式進行編碼:
value = second
+ minute * 102
+ hour * 104
+ day * 106
+ month * 108
+ year * 1010
DateTime2
:「新」的 DATETIME
編碼為 5 位元組的大端位元組,並帶有 0 到 3 個位元組的可選小數部分,小數部分的處理方式如先前所述。高 5 個位元組的編碼如下所示:
YearMonth
位元編碼為 Year = YearMonth / 13
和 Month = YearMonth % 13
。
Timestamp
:此類型的「舊」版本使用 32 位元無符號值,表示自 Unix epoch 以來的經過秒數,並以主機位元組順序儲存。
Timestamp2
:這是TIMESTAMP
的「新」版本,整數部分使用 4 個位元組,並採用大端位元組編碼(無符號)。可選的 3 位元組小數部分按照本節前面所述的方式進行編碼。
其他資訊。 有關 NDB API 中表示的資料類型的更多資訊和範例,可以在 ndb/src/common/util/NdbSqlUtil.cpp
中找到。此外,請參閱第 2.5.14 節「Timestamp2 範例」,其中提供了使用 Timestamp2
資料類型的簡單 NDB API 應用程式範例。