MySQL - 列类型(字符串类型)

在SQL中,将字符串类型分为了六类:char,varchar,text,blob,enum和set。

MySQL - 列类型(字符串类型)_第1张图片


【1】定长字符串char

磁盘(二维表)在定义结构的时候,就已经确定了最终数据的存储长度。

Char(L):L代表length,可以存储的长度,单位为字符,最大长度值可以为255。

char(4):在UTF8环境下,需要4*3=12个字节存储空间;GBK编码环境下需要4*2=8个字节存储空间(在java中使用两个字节来表示一个字符)。

Java基本类型占用的字节数:
1字节: byte , boolean
2字节: short , char
4字节: int , float
8字节: long , double
注:1字节(byte)=8位(bits)


【2】变长字符串varchar

变长字符串在分配空间的时候按照最大长度的空间分配,实际用了多少根据具体的数据来定。

Varchar(L) : L表示字符长度,理论可以存储65536个字符。会多出1-2个字节来确定存储的实际长度。如果字符长度大于255,那么既不使用定长,也不使用变长,而是使用文本字符串text

Varchar(10):储存10个汉字,UTF8下使用10*3+1=31个字节(大于255使用两个字节存储)。

以下占用字节,均表示在分配空间的时候所需要的字节(字符概念,一个字符使用三个字节存储-UTF8),如A占用字节为3,但是MySQL自身存储的时候会使用一个字节存储(会对英文字母和符号进行优化):

MySQL - 列类型(字符串类型)_第2张图片

在生产环境中如何选择定长或者变长字符串类型呢?

定长的磁盘空间比较浪费,但是效率高:如果数据长度基本一样,就选择定长;如身份证,手机号码等。

变长的磁盘空间比较节省,但是效率低:如果数据不能确定长度(不同数据长度有变化),如姓名,地址等。


【3】文本字符串

如果数据量超过255个字符,通常会使用文本字符串。

文本字符串根据存储的数据格式进行分类:

Text:存储文字;
Blob:存储二进制数据,如图片、音频等。

通常二进制数据实际上数据库存储路径,物理文件放在磁盘上面。


【4】枚举

枚举:enum,事先将所有出现的结果都设计好,实际存储的数据必须是预先规定的数据的一个。

其作用如下:

① 规范数据格式,数据只能是规定的数据中的其中一个;

② 节省存储空间,枚举通常有一个别名-单选框;枚举实际存储的是数值而不是字符串本身。

create table my_enum(
gender enum('男','女','保密')
)charset utf8;

desc my_enum;

MySQL - 列类型(字符串类型)_第3张图片

测试如下:

insert into my_enum VALUES('男');--有效数据
insert into my_enum VALUES('人妖');--无效数据

MySQL - 列类型(字符串类型)_第4张图片

insert into my_enum VALUES('男女');--无效数据

MySQL - 列类型(字符串类型)_第5张图片


Tips:

在MySQL中,系统也是自动转换数据格式的,尤其是字符串转数字。如字符串若非数字,将转换为0;若以数字开头则转换为对应的开头数字。

select 1+'hello',1+'1hello',1+'2hello','1.0hello',1+'1.1hello',1+'1.1.1hello',1+'1.2.1hello';

MySQL - 列类型(字符串类型)_第6张图片


查看一下刚才插入的数据在MySQL是如何存储的:

select gender, gender+0 from my_enum 

MySQL - 列类型(字符串类型)_第7张图片


枚举原理如下】:

枚举在进行数据规范的时候(定义的时候),系统会自动建立一个数字与枚举元素的对应关系(关系放到日志中)。

在进行数据插入的时候,系统自动将字符转换成对应的数字进行存储;然后在进行数据提取的时候,系统将其转换为字符进行显示。

枚举插入数字:

insert into my_enum VALUES('1'),('2'),('3');--会插入'关系'中对应的字符串,存储的是字符串对应的数字;
select gender, gender+0 from my_enum 

MySQL - 列类型(字符串类型)_第8张图片


【5】集合字符串

集合跟枚举很相似,实际存的是数字而不是字符串本身(集合是多选),区别与枚举,别名可以称为复选框!!!

Set(元素列表),可以使用元素列表中的多个元素,元素之间可以使用逗号分隔。

这里写图片描述

说明:1,2,3,4,8 ;分别对应tinyint,smallint,mediumint,int,bigint。在底层存储的时候,使用整型存储的(存储字符对应的数字,而不是字符本身,参考enum)。

如有8个元素,那么使用1个子节存储(tinyint);16个元素使用两个字节存储(smallint);33个元素使用8个字节存储(bigint)。远比varchar或者char占用磁盘空间少得多。

如果是varchar,8个元素,那么需要24+1=25个字节;但是set只需要1个字节。


create table my_set(
hobby SET('篮球','足球','乒乓球','羽毛球','排球','台球','网球','棒球')
)charset utf8;

DESCRIBE my_set

MySQL - 列类型(字符串类型)_第9张图片

insert into my_set VALUES('足球,篮球');--插入的时候不用考虑顺序,服务器存储的时候会自动寻找对应位置,看下面分析。。

insert into my_set VALUES('足球');

insert into my_set VALUES('足球篮球');--无效数据,未用逗号分隔

insert into my_set VALUES('小球,篮球');--不存在的数据

insert into my_set VALUES(4);--直接插入数字

.....
select hobby,hobby+0 from my_set ORDER BY hobby ASC;

MySQL - 列类型(字符串类型)_第10张图片


是不是存的数字出乎意料?不再是1,2,3。。。

分析如下图:

这里写图片描述

那么插入数字255时(因为八个位全为1),对应全部字符串:

insert into my_set VALUES(255);

select hobby,hobby+0 from my_set ORDER BY hobby ASC;

MySQL - 列类型(字符串类型)_第11张图片

set如此节省磁盘空间,但是生产中并未常使用!因为效率优先!!!所以enum和set使用频率并不如varchar高!!!

你可能感兴趣的:(MySQL)