字符型

BIT

BIT和VARBIT 数据类型存储二进制位数组。其中,BIT的长度是固定的,VARBIT的长度是可变的。

别名

在InCloud ZNBASE中,VARBIT的别名是BIT VARYING。

语法

位数组常量表示一个字面量。 例如,B’100101’表示一个6位的数组。一个BIT类型的值占用位的个数,按照下表确定:

类型声明逻辑大小
BIT1 bit
BIT(N)N bit
VARBIT无最大值限制的可变长度
VARBIT(N)最多N bit的可变长度

​ BIT值的有效大小比其逻辑位数大一个有界常数。 在数据库内部,InCloud ZNBASE以64位为增量存储位数组,此外再用一个额外的整数值来编码长度。

​ BIT值的总存储大小可以任意大,但是建议将值保持在1 MB以下以保证性能。超过该阈值,写放大和其他考虑因素可能导致性能显着下降。

类型转换

BIT值可以强制转换为以下任何数据类型:

类型描述
INT将BIT数组转换为相应的数值。将这些位按照二进制补码编码进行解释。如果BIT数组大于整数类型,则将忽略左侧多余的位。 例如,B’1010’:: INT等于10。
STRING将二进制数字打印为字符串。这些位将被解释为其字面量。 例如,B’1010’:: STRING等于’1010’。
示例

示例1:创建具有BIT列的表。

CREATE TABLE bits (c1 BIT, c2 BIT(3), c3 VARBIT, c4 VARBIT(3));

CREATE TABLE

SHOW COLUMNS FROM bits;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

c1 | BIT | true | NULL | | {} | false

c2 | BIT(3) | true | NULL | | {} | false

c3 | VARBIT | true | NULL | | {} | false

c4 | VARBIT(3) | true | NULL | | {} | false

rowid | INT | false | unique_rowid() | | {primary} | true

示例2:向具有BIT列的表中新增数据。

INSERT INTO bits VALUES (B’1’, B’101’, B’1’, B’1’);

INSERT 1

SELECT * FROM bits;

c1 | c2 | c3 | c4

+——+——-+——+——+

1 | 101 | 1 | 1 (1 row) |

对于BIT和BIT(N)类型,值的宽度大小必须完全匹配。

INSERT INTO bits(c1) VALUES (B’101’);

pq: bit string length 3 does not match type BIT

INSERT INTO bits(c2) VALUES (B’10’);

pq: bit string length 2 does not match type BIT(3)

对于VARBIT类型,该值不能大于指定的最大宽度:

INSERT INTO bits(c4) VALUES (B’1011’);

pq: bit string length 4 too large for type VARBIT(3)

示例3:数据类型转换

BIT类型可以转换为INT和STRING类型。

SELECT B’1011’::INT;

int

+——-+

11

SELECT B’1011’::STRING;

string

+————+

1011

SELECT B’111101’::BIT(3);

bit(3)

+————+

111

SELECT B’111101’::VARBIT(3);

varbit(3)

+—————-+

111

​ 如果显式地把一个位串值转换成BIT(n),那么它的右边将被截断或者在右边补齐零,直到刚好n位,而且不会抛出任何错误。类似地,如果显式地把一个位串数值转换成VARBIT(n),如果它超过了n位,那么它的右边将被截断。

BYTES

BYTES数据类型存储可变长度的二进制字符串。

别名

在InCloud ZNBASE中,BYTES的别名有:

  • BYTEA

  • BLOB

语法

要表示字节数组常量,可以参考BYTE数组章节。。例如,以下三个是相同字节数组的等效文字表示:

  • b’abc’,
  • b’\ 141 \ 142 \ 143’,
  • b’\ x61 \ x62 \ x63’。

​ 除了这种语法之外,InCloud ZNBASE还支持使用字符串文字,包括在上下文中的语法’…’、e’…’和x’….’。BYTES的存储大小是可的,但建议将值保持在1MB以下以保证性能。如果高于该阈值,写入放大和其他因素可能会导致显着的性能下降。

类型转换

总是可以成功将BYTES显式转换为STRING。数据库支持两种转换模式,由会话变量bytea_output控制:

  • hex(默认)

转换的输出以两个字符’\x’开头,字符串的其余部分由输入中每个字节的十六进制编码组成。例如,x’48AA’:: STRING产生’\ x48AA’。

  • escape

转换的输出包含输入中的每个字节。如果是ASCII字符,则保持原样;否则,使用八进制转义格式\ NNN进行编码。例如,x’48AA’:: STRING产生’0 \ 252’。

可以将STRING值显式转换为BYTES。如果十六进制数字无效或十六进制数字为奇数,则此转换将失败。支持两种转换模式:

  • 字符串以’\x’开头

如果字符串以两个特殊字符’\x’开头(例如\ xAABB),则字符串的其余部分将被解释为十六进制数字序列。然后将字符串转换为字节数组,其中每对十六进制数字都转换为一个字节。

  • 字符串不以’\x’开头

如果字符串不以’\x’开头,该字符串将转换为包含其UTF-8编码的字节数组。

STRING与BYTES对比

​ 尽管在许多情况下,STRING和BYTES似乎都表现出相似的行为,但在将它们转换为另一种之前,应先了解它们的细微差别。STRING将其所有数据视为字符,或更具体地说,将其视为Unicode编码点。

​ BYTES将其所有数据视为字节字符串。在实现上的这种差异可能导致行为发生显著不同。我们用一个复杂的Unicode字符来举例,例如☃(雪人emoji表情符号):

SELECT length(‘☃’::string);

length

+————+

1

SELECT length(‘☃’::bytes);

length

+————+

3

​ 在上例中,LENGTH(string)测量字符串中包含的Unicode编码点的数量,而LENGTH(bytes)测量存储该值所需的字节数。每个字符(或Unicode编码点)可以使用多个字节进行编码,因此两者输出存在差异。

将字面量转换成 STRING vs. BYTES

通过SQL客户端输入的文字将根据类型转换为其他值:

  • BYTES

BYTES在开头对’\x’赋予特殊含义,并通过将十六进制数字替换为单个字节来转换其余部分。例如,’\xff’等效于值为255的单个字节。有关更多信息,参考字符串的转义符章节。

  • STRING

STRING没有给’\x’赋予特殊含义,因此所有字符都被视为不同的Unicode代码点。 例如,’\ xff’被视为长度为4(\,x,f和f)的STRING。

示例

示例1:创建具有BYTES列的表。

CREATE TABLE bytes (c1 INT PRIMARY KEY, c2 BYTES,c3 BYTEA);

CREATE TABLE

SHOW COLUMNS FROM bytes;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

c1 | INT | false | NULL | | {primary} | false

c2 | BYTES | true | NULL | | {} | false

c3 | BYTEA | true | NULL | | {} | false

BYTEA和BLOB的实际数据类型都是BYTES。

示例2:向具有BYTES列的表中插入数据。

INSERT INTO bytes(c1,c2) VALUES (1, b’\141\142\143’), (2, b’\x61\x62\x63’), (3, b’\141\x62\c’);

INSERT 3

SELECT * FROM bytes;

c1 | c2 | c3

+——+——-+———+

1 | abc | NULL

2 | abc | NULL

3 | abc | NULL |

STRING

在InCloud ZNBASE中,STRING数据类型存储一串Unicode字符。

别名

在InCloud ZNBASE中,STRING的别名有:

  • CHARACTER

  • CHAR

  • VARCHAR

  • TEXT

STRING(n)的别名有:

  • CHARACTER(n)
  • CHARACTER VARYING(n)
  • CHAR(n)
  • CHAR VARYING(n)
  • VARCHAR(n)

​ 使用STRING(n)来限制STRING列的长度,其中n是允许的最大Unicode编码点数量(通常被认为是“字符”)。如果没有指定长度,CHAR、CHARACTER长度默认为1。

插入字符串时:

  • 如果值超过列的长度限制,InCloud ZNBASE将会报错。

  • 如果该值被转换为具有长度限制的字符串(例如,CAST(‘hello world’AS STRING(5))),则InCloud ZNBASE将截断到限制长度。

  • 如果该值未达到列的长度限制,InCloud ZNBASE会添加填充字符。这适用于STRING(n)和其所有别名。

语法

STRING类型的值可以使用多种格式表示,可以参考SQL语言基础字符串章节。

在SQL Shell中打印出STRING值时,如果值不包含特殊字符,则Shell使用简单的SQL字符串文字格式,否则使用转义格式。

归类(Collations)

STRING值接受归类,它允许你根据特定语言和国家/地区的规则对字符串进行排序。

但是,需要注意的是:不能在索引或主键中使用归类的字符串。这样做会导致InCloud ZNBASE崩溃。

存储大小

STRING值的大小是可变的,但建议将值保持在64k字节以下以保证性能。高于该阈值,写放大和其他因素可能导致明显的性能下降。

类型转换

STRING可以转换为以下数据类型:

类型细节
BIT需要支持的BIT字符串格式,例如’101001’。且由于BIT类型长度为1字节,推荐使用VARBIT进行类型转换,或者指定长度。例如select ‘101001’::varbit;。
BOOL需要支持的BOOL字符串格式,例如’true’。
BYTES有关更多详细信息,请参见此处。
DATE需要支持的DATE字符串格式,例如’2016-01-25’。
DECIMAL需要支持的DECIMAL字符串格式,例如’1.1’。
FLOAT需要支持的FLOAT字符串格式,例如’1.1’。
INET需要支持的INET字符串格式,例如’192.168.0.1’。
INT需要支持的INT字符串格式,例如’10’。
INTERVAL需要支持的INTERVAL字符串格式,例如’1h2m3s4ms5us6ns’。
TIME需要支持的TIME字符串格式,例如’01:22:12’(微秒精度)。
TIMESTAMP需要支持的TIMESTAMP字符串格式,例如’2016-01-25 10:10:10.555555’。
示例

下面通过一个例子,介绍STRING类型在数据库中的应用:

CREATE TABLE strings(c1 STRING PRIMARY KEY, c2 CHARACTER, c3 CHAR, c4 VARCHAR, c5 TEXTT, c6 STRING(5));

SHOW COLUMNS FROM strings;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+——————-+—————-+ +——————-+—————-+——————-+————————+———————————-+—————-+—————-+

c1 | STRING | false | NULL | | {primary} | false

c2 | CHARACTER | true | NULL | | {} | false

c3 | CHAR | true | NULL | | {} | false

c4 | VARCHAR | true | NULL | | {} | false

c5 | TEXT | true | NULL | | {} | false

c6 | STRING(5) | true | NULL | | {} | false

(6 rows)

INSERT INTO strings VALUES (‘a1b2c3d4’, ‘s’, ‘9’, ‘e5f6’, ‘g7h8i9’);

INSERT 1

SELECT * FROM strings;

c1 | c2 | c3 | c4 | c5 | c6

+—————+——+——+———+————+———+

a1b2c3d4 | s | 9 | e5f6 | g7h8i9 | NULL |

COLLATE

​ COLLATE功能允许你根据语言和国家/地区特定的规则对STRING进行排序,称为归类。

​ 对字符串归类很重要,因为不同的语言对字母顺序有不同的规则,特别是关于重音字母。例如,在德语中,重音字母与非重音字母一起排序;而在瑞典语中,它们位于字母表的末尾。排序规则是用于排序的一组规则,通常对应于一种语言;但有些语言有多种排序规则,排序规则不同。例如,葡萄牙语对巴西和欧洲方言分别进行了整理(分别为pt-BR和pt-PT)。

​ 对归类字符串的操作不能涉及具有不同排序规则的字符串或不具有排序规则的字符串。但是,可以动态添加或覆盖排序规则。建议仅在需要按特定排序规则对字符串排序时才使用排序规则功能,因为每次构造或加载归类字符串到内存中时,InCloud ZNBASE会计算其排序规则key,其大小与归类字符串的长度成线性关系,这需要耗费额外的资源。

​ 归类字符串可能比相应的未归类字符串大得多,具体取决于语言和字符串内容。例如,包含字符é的字符串在法语区域设置中产生比在中文中更大的归类键。与未归类字符串相比,索引的归类字符串需要额外的磁盘空间。在索引归类字符串的情况下,除了从中派生它们的字符串之外,还必须存储归类键,从而产生恒定的开销比例。

支持的归类

​ InCloud ZNBASE支持Go语言包提供的归类。<collation>参数是每行末尾的BCP47语言标记,其后紧跟“//”。 例如,南非语通过af归类进行支持。

语法

归类字符串作为SQL中的常规字符串使用,不过会跟随着一个COLLATE子句。

列语法支持

STRING COLLATE <collation>。

当然,可以使用STRING的别名。例如:

CREATE TABLE collates(c1 STRING COLLATE en PRIMARY KEY,c2 TEXT COLLATE en);

值语法支持

<STRING value> COLLATE <collation>。

例如:

INSERT INTO collates VALUES (‘tianjin’ COLLATE en,’ZNBASE’ COLLATE en);

示例

示例1:为一列制定排序规则。可以为STRING列中的所有值设置默认排序规则。例如,设置一列的默认collation为中文 (zh):

CREATE TABLE collates(c1 STRING COLLATE zh PRIMARY KEY, c2 TEXT COLLATE zh);

将值插入此列时,必须为每个值指定collation:

INSERT INTO collates VALUES (‘北京’ COLLATE zh,’ZNBASE’ COLLATE zh),(‘济南’ COLLATE zh,’ZNBASE’ COLLATE zh),(‘天津’ COLLATE zh,’ZNBASE’ COLLATE zh); INSERT 3 |

排序现在将按照zh处理:

> SELECT * FROM collates ORDER BY c1; c1 | c2 +———+———+ 北京 | ZNBASE 济南 | ZNBASE 天津 | ZNBASE (3 rows)

示例2:通过非默认规则排序

可以使用特定的排序规则而不是默认排序规则对列进行排序。例如,如果按普通话(cmn)和粤语(yue)排序结果,则可能会得到不同的结果:

SELECT * FROM collates ORDER BY c1 COLLATE cmn;

c1 | c2

+———+———+

北京 | ZNBASE

济南 | ZNBASE

天津 | ZNBASE

SELECT * FROM collates ORDER BY c1 COLLATE yue;

c1 | c2

+———+———+

北京 | ZNBASE

天津 | ZNBASE

济南 | ZNBASE

示例3:临时转换归类

可以动态地将任何STRING转换为带有排序规则的字符串:

SELECT ‘A’ COLLATE de < ‘Ä’ COLLATE de;

?column?

+—————+

true (1 row) |

但是不能比较具有不同归类的值:

SELECT ‘Ä’ COLLATE sv < ‘Ä’ COLLATE de;

pq: unsupported comparison operator: <collatedstring{sv}> < <collatedstring{de}>

还可以通过使用强制转换从值中删除排序规则。

SELECT CAST(name AS STRING) FROM de_names ORDER BY name;

name

+—————+

Backhaus Baz Br |

BLOB

​ BLOB即二进制大型对象(Binary LargeObject),用以存储非文本的字节流数据(如程序、图象、影音等)。InCloud ZNBASE支持BLOB数据类型,但建议将存储对象的大小保持在64M以下以保证数据库性能。

示例

示例1:创建具有BLOB列的表。

CREATE TABLE blobs (c1 INT PRIMARY KEY, c2 BLOB);

CREATE TABLE

SHOW COLUMNS FROM blobs;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

c1 | INT | false | NULL | | {primary} | false

c2 | BLOB | true | NULL | | {} | false |

示例2:向具有BLOB列的表中插入数据,需要使用decode(data,format)对图片数据进行解码成数据库可以识别的BLOB类型,可以选择的解码方式有:hex/escape/ base64。

INSERT INTO blobs VALUES(1, decode(‘FFD8FFE000104A46494600010100000100010000FF’,’hex’));

INSERT 1

insert into blobs values(2, decode(‘FFD8FFE000104A46494600010100000100010000FF’,’escape’));

INSERT 1

SELECT * FROM blobs;

c1 | c2

+——+—————————————————————————————————————+ 1 | \377\330\377\340\000\020JFIF\000\001\001\000\000\001\000\001\000\000\377 2 | FFD8FFE000104A46494600010100000100010000FF |

CLOB

​ CLOB,即字符型大型对象(Character LargeObject),与字符集相关,用以存储文本型的数据(如历史档案、大部头著作等)。InCloud ZNBASE支持CLOB数据类型,但建议将存储对象的大小保持在64M以下以保证数据库性能。

示例

示例1:创建具有CLOB列的表。

CREATE TABLE clobs (c1 INT PRIMARY KEY, c2 CLOB);

CREATE TABLE

SHOW COLUMNS FROM clobs;

column_name | data_type | is_nullable | column_default | generation_expression | indices | is_hidden

+——————-+—————-+——————-+————————+———————————-+—————-+—————-+

c1 | INT | false | NULL | | {primary} | false

c2 | CLOB | true | NULL | | {} | false

示例2:向具有CLOB列的表中插入数据。

INSERT INTO clobs VALUES(1, ‘浪潮云海分布式数据库’);

INSERT 1

SELECT * FROM clobs;

c1 | c2

+——+———————————+

1 | 浪潮云海分布式数据库