一、char和varchar类型
char和varchar类型类似,都用来存储字符串,但是它们保存和检索字符串的方式不同。char属于固定长度的字符类型,varchar属于可变长度的字符类型。例如:对于char(4)和varchar(4)这两种类型定义来说:
(1)、''在char(4)中占了4个字节长度,varchar(4)则只占用一个字节的长度;
(2)、'ab'在char(4)中占了4个字节长度,varchar(4)中则只占用了3个字节的长度;
(3)、'abcd'在char(4)中占用了4个字节长度,在varchar(4)中则占用了5个字节的长度;
为何在varchar类型中会多出一个字节长度呢?这是因为varchar类型将这多出的一个字节用于保存varchar类型实际使用了多大的长度。char(4)和varchar(4)的检索并不总是相同的,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13
MySQL> create table char_and_varchar (v varchar(4),c char(4)); Query OK, 0 rows affected (0.20 sec) mysql> insert into char_and_varchar values ('ab ','ab '); Query OK, 1 row affected (0.33 sec) mysql> select concat(v,'cd'),concat(c,'cd') from char_and_varchar; +----------------+----------------+ | concat(v,'cd') | concat(c,'cd') | +----------------+----------------+ | ab cd | abcd | +----------------+----------------+ 1 row in set (0.35 sec)
由于char是固定长度的,所以它的处理速度比varchar快的多,但其缺点是浪费存储空间,程序需要对尾部空格进行处理等缺点,所以多那些长度变化不大并且对查询速度有较高要求的的数据可以考虑使用char类型来存储。随着MySQL版本的不断升级,varchar数据类型的性能也将不断提升,varchar类型的应用范围更加广泛。
在MySQL中,不同的存储引擎对char和varchar的使用原则有所不同:
(1)、在MyISAM存储引擎中,建议使用固定长度的字段类型代替可变长度的字段类型。
(2)、在Memory存储引擎中,目前都是用固定长度的数据行存储,因此无论是char还是varchar类型,都将转化为char类型处理。
(3)、在InnoDB存储引擎中,建议使用varchar类型。
二、TEXT和BLOB
在保存少量字符串的时候,可以使用char和varchar数据类型。在保存较大的文本时,通常会选择使用text或BLOB。两者之间的主要差别是:BLOB能用来保存二进制数据,例如:照片,而text只能用于保存字符类型数据。text和BLOB中又分别包括text、mediumtext、longtext和blob、mediumblob、longblob三种不同的类型。它们之间的主要区别是存储文本的长度不同和存储字节不同。
使用BLOB和TEXT类型应注意的一些问题:
(1)、BLOB和TEXT会引起一些性能问题,特别是在执行了大量的删除操作时。删除操作会在数据表中留下很大的“空洞”,以后填入这些“空洞”的记录在插入性能上会有影响。为了提高性能,应定期使用OPTIMIZETABLE功能对这类表进行碎片整理,避免空洞导致性能问题。
(2)、使用合成的索引来提高大本文字段的查询性能。所谓合成索引就是根据大文本字段的内容建立一个散列值,并把这个值存储在单独的数据列中,然后就可以通过散列值找到数据行了。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
mysql> create table t (id varchar(100),content blob,hash_value varchar(40)); Query OK, 0 rows affected (0.03 sec) mysql> insert into t values (1,repeat('beijing',2),md5(content)); Query OK, 1 row affected (0.33 sec) mysql> insert into t values (2,repeat('beijing',2),md5(content)); Query OK, 1 row affected (0.01 sec) mysql> insert into t values (2,repeat('beijing 2008',2),md5(content)); Query OK, 1 row affected (0.01 sec) mysql> select * from t; +------+--------------------------+----------------------------------+ | id | content | hash_value | +------+--------------------------+----------------------------------+ | 1 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 | | 2 | beijingbeijing | 09746eef633dbbccb7997dfd795cff17 | | 2 | beijing 2008beijing 2008 | 1c0ddb82cca9ed63e1cacbddd3f74082 | +------+--------------------------+----------------------------------+ 3 rows in set (0.00 sec) mysql> select * from t where hash_value=md5(repeat('beijing 2008',2)); +------+--------------------------+----------------------------------+ | id | content | hash_value | +------+--------------------------+----------------------------------+ | 2 | beijing 2008beijing 2008 | 1c0ddb82cca9ed63e1cacbddd3f74082 | +------+--------------------------+----------------------------------+ 1 row in set (0.00 sec)