一、字符串类型

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

1.1 定长字符串

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

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

Char(4):在UTF8环境下,需要4*3=12个字节。

1.2 变长字符串

定义:varchar,在分配空间的时候,按照最大的空间分配,但是实际上最终用了多少,是根据具体的数据来确定。

Varchar(L): L表示字符长度,理论长度是65536个字符,但是会多出1到2个字节来确定存储的实际长度

Varchar(10): 的确存了10个汉字,UTF8环境,10*3+1=31

存储了3个汉字,UTF8环境,3*3+1=10(bytes)

定长与变长的存储实际空间(UTF8)

存储实际空间

Char(4)
Varchar(4)
Char占用字节
Varchar占用字节
ABCD
ABCD
ABCD
4*3=12
4*3+1=13
A
A
A
4*3=12
1*3+1=4
ABCDE
×
×

数据超过长度

数据超过长度

如何选择定长或者是变长字符串呢?

定长的磁盘空间比较浪费,但是效率高:如果数据基本上确定长度都一样,就是使用定长,如:身份证,电话号码,手机号码等

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

1.3  文本字符串

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

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

Text:  存储文字(二进制数据实际上都是存储路径)

Blob: 存储二进制数据(通常不用)

1.4 枚举字符串

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

枚举的使用方式

定义:enum(可能出现的元素列表); //如 enum(‘男’,‘女’,‘不男不女’,‘妖’,‘保密’);

使用:存储数据,只能存储上面定义好的数据

(a) 创建枚举表

1 CREATE TABLE my_enum(gender enum('男','女','保密')) charset utf8;

(b)加入数据  作用之一:规范数据格式;数据只能是规定的数据的其中一个

1 insert into my_enum values('男'),('保密'); --有效数据

2 insert into my_enum values('male'); --错误数据(没有male元素)

(b)作用之二:节省存储空间(枚举通常有一个别名:单选框):枚举实际存储的是数值而不是字符串本身。

在MYSQL中,系统也是字段转换成数据格式的:而且基本与PHP一样(尤其是字符串转数字)

证明字段存储的数据是数值:将数据取出来+0 就可以判断出原来的数据存的到底是字符串还是数值:如果是字符串最终结果永远为0,否则就是其他值。

(c)  将字段结果取出来进行+0运算

1 select gender+0,gender from my_enum;

找出来枚举元素的实际规律:按照元素出现的顺序,从1开始编号

enum

1,2, ~枚举选项量(65535)

内部存储是整型表示。字段值只能是某一个

枚举原理:枚举在进行数据规范的时候(定义的时候),系统会自动建立一个数字与枚举元素的对应关系(关系放到日志中):然后在进行数据插入的时候,系统自动将字符转换成对应的数字存储,然后在进行数据提取的时候,系统自动将数值转换成对应的字符串显示。

因为枚举实际存储的是数值,所以可以直接插入数值

(d)数值插入枚举元素

1 insert into my_enum values(1),(2);2 select gender+0,gender from my_enum;

1.5 集合字符串

集合跟枚举很类似:实际存储的是数值,而不是字符串(集合是多选)

集合使用方式

定义:Set(元素列表)

使用:可以使用元素列表中的元素(多个),使用逗号分隔

Set

1、2、3、4、8。元素数量:64

(a) 创建集合表

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

0 1 0 0 0 1 1 0

集合中:每一个元素都是对应一个二进制位,被选中为1,没有则为0;最后反过来。

反过来:  01100010=98

(b) 插入数据:可以使用多个元素字符串组合,也可以直接插入数值

1 insert into my_set values('足球,台球,网球');2 insert into my_set values('3'); --代表乒乓球;3=1+2=篮球+足球

查看数据:数值+数据查看

(c)查看集合数据

1 select hobby +0,hobby from my_set; --- 预料之外的结果

98转成二进制=64+32+2=01100010

(d)集合中每一个元素都是对应一个对应二进制位

1 insert into my_set values(255); --255对应二进制为11111111

集合中元素的顺序没有关系;最终系统都会去匹配顺序

颠倒元素出现的顺序

insert into my_set values('网球,台球,足球');select * from my_set;

集合的强大在于能够规范和节省空间:PHP也可以规范数据,但是对于PHP来说效率优先,而且数据的维护可以用通过数字进行,增加PHP的维护成本;PHP根本没有办法判断数据在数据库的形式。