sql数据库的char,varchar,text,blob类型比较

1.char

char(n):n表示字符数,最大长度是255个字符。如果是utf8编码方式, 那么char类型占255 * 3个字节。(utf8下一个字符占用1至3个字节)。

1.1 mysql数据库

mysql官网参考手册提到这句话“一个长度CHAR列被固定在创建表声明的长度。长度可以是0到255之间的任何值。CHAR 存储值时,它们会用空格右填充到指定的长度。当CHAR被检索到的值,拖尾的空格被删除。”这句话怎么理解呢,用以下实验验证:

    当定义n=5时,传入字符串"abc",那么实际存储时,会再加上两个空格填充到数据库,但读出来还是3个字节。但是我们发现一个问题,当你存入的字符串就是"a  ",字符串尾部就带有两个空格,那么读取时会变成"a"。因为拖尾的空格被删除。所以当每次传入的是非固定的值,一定要慎用char(n)。

1.2 PG数据库

 其官网参考手册说明"类型char(n)的值物理上都用空白填充到指定的长度n, 并且以这种方式存储和显示。不过,拖尾的空白被当作是没有意义的,并且在比较两个 character类型值时不会考虑它们。在空白有意义的排序规则中,这种行为可能会 产生意料之外的结果,例如SELECT 'a '::CHAR(2) collate "C" < 'a\n'::CHAR(2)会返回真。尽管C语言认为空格大于换行符。当把一个character值转换成其他 字符串类型之一时,拖尾的空白会被移除。"为验证这句话测试如下:

    当定义n=5时,传入字符串"abc",那么实际存储时,会再加上两个空格填充到数据库,但读出来是5个字节。即空白填充是会显示出来的。这种也会有问题,因为存入是"abc",但读出是"abc  "。所以当每次传入的是非固定的值,也要慎用char(n)。

1.3 sqlite3数据库

character(n) 测试发现:传入和传出是一致的,即使有字符串尾部有空白,也未被删除或多加。

2.varchar

varchar可变长度,可以设置最大长度;适合用在长度可变的属性。VARCHAR值在存储时不会填充。根据标准SQL,在存储和检索值时保留尾随空格。

sql的标准要求列类型定义为char(n),varchar(n)时,当插入数据超过n个字符,数据会被截断存入数据库,但并不报错。

2.1 mysql数据库

MySQL5.0.3以前版本varchar(n)中的n表示字节数;即如果存放的时UTF8汉字时(每个汉字3字节),则n=20表示只能存放6个汉字;并且最大长度限制为255。

MySQL5.0.3以后版本varchar(n)中的n表示字符数;n=20表示无论时数字字母还是UTF8汉字时都可以时20个,但是最大大小时65532字节。也就是说可以存放65532个字节(注意是字节而不是字符!!!)的数据(起始位和结束位占去了3个字节)。如果字段default null(即默认值为空),整条记录还需要1个字节保存默认值null。

所以对在5.0.3以前版本中需要使用固定的TEXT或BLOB格式存放的数据可以在高版本中使用可变长的varchar来存放,这样就能有效的减少数据库文件的大小。

2.2 PG数据库

官方指导手册未显示指明n最大值,但在代码里可以看到

n 最大#define MaxAttrSize     (10 * 1024 * 1024) 即10485760个字符

2.3 sqlite3数据库

The current implementation will only support a string or BLOB length up to 231-1 or 2147483647.

3. text

不需要设置最大长度,只要在数据库允许范围内都可以存储长度可变的字符串,在存储时不会填充,在存储和检索值时保留尾随空格。

3.1 mysql数据库

TINYTEXT 256 bytes  
TEXT 65,535 bytes ~64kb
MEDIUMTEXT  16,777,215 bytes ~16MB
LONGTEXT 4,294,967,295 bytes ~4GB

由于varchar查询速度更快, 能用varchar的时候就不用text。

mysql里text列是不可以设置默认值的。

给text列建立索引时,必须指定索引前缀长度,因为索引大小是有范围的,否则建立索引会失败。所以也不一定不能成为主键。

      官方指导文档提到"如果对某TEXT列建立索引,则索引条目比较将在末尾加空格。这意味着,如果索引要求唯一值,则仅尾随空格数量不同的值会发生重复键错误。例如,如果表包含'a',则尝试存储'a '会导致重复键错误。对于BLOB列则不是这样。"为此测试如下:

对text类型列设置唯一索引且最左长度为3,先插入"a"成功,再插入"a ",发现会失败报重复了。所以对text加唯一索引要慎重。

3.2 PG数据库

varchar未指定n与 text等同,它们只受允许存储的最长字串长度限制,1 GB左右。

PG数据指出char(n)并不像其他数据库更具优势,反而是最慢的,更推荐使用varchar或者text.

对其添加唯一索引,不会对尾部空白特殊处理。

4.blob

4.1 mysql数据库

mysql 对blob的支持,有binary(n)和varbinary(n),以及TinyBlob、Blob、MediumBlob、LongBlob,用法也非常类似char(n)/varchar(n)/text。 但注意这里的n就是字节长度。

类型 大小(单位:字节)
binary(n) n最大255
varbinary(n) n最大65535,~64K
TinyBlob 最大255
Blob 最大65K
MediumBlob 最大16M
LongBlob 最大4G

BINARY:官方指导文档说明”当BINARY被存储的值,它们被右侧填充垫值到指定的长度。填充值为0x00(零字节)。值在0x00插入时用右填充,不会删除尾随字节以进行检索。所有字节在比较中都很重要,包括ORDER BY和DISTINCT操作。 0x00比较中,空间和空间有所不同,0x00先于空间进行 排序。

       示例:对于BINARY(3)列, 在插入时'a '变为 'a \0'。 插入时'a\0'变为'a\0\0'。两个插入的值均保持不变以进行检索。“ 根据这个例子,可以发现binary(n)与char(n)对于存入时再读取处理是不一样的,binary读取时是只根据n长度填充的0值也会读出来,并且binary填充的是0值而非空格

VARBINARY:没有用于插入的填充,也没有剥离任何字节以进行检索。

blob:与text类似,blob类型不能直接建立索引,必须指定最左前缀,所以也不能作为主键。根据上面提到的binary(n)存入说明,再建立最左前缀索引比如3个字节最左的唯一索引,插入'a\0'后再插入'a'会报唯一键重复。

4.2 PG数据库

blob可以用bytea存储,它们只受允许存储的最长字串长度限制,1 GB左右。

允许建立unique index或者普通index,但是index本身是有大小限制的,所以当bytea自己数比较大时,再对它建立索引就会失败。

允许为NULL值。

4.3 sqlite3数据库

sqlite3至少从官网没找到相关的说明。倒是从一些博客上看到提供binary(n),varbinary(n),image三种类型,使用起来类似char(n), varchar(n), text。

但是,经过测试发现,设置n应该没什么用,虽然建表语句显示也是带n的,但是当存储超过n个字节时比如n+5,依然可以存入和读取,读出的也是n+5个字节。比如binary(16),存入3个字节时,读出的也依然是3个字节。如果第3个字节是0值,也会一样的值读出来。

至于有的博客还说binary/varbinary上限是8000字节,但是我存到9000也依然可以正常读取。

上限测1GB,程序崩溃了,至少测试65535以上个字节还是可以的。

猜你喜欢

转载自blog.csdn.net/yshhuan/article/details/114064059
今日推荐