分类: Mysql/postgreSQL
2013-05-16 18:09:58
原则:
一、更小——一般来来说,要试着使用能正确地存储和表示数据的最小类型。
二、简单——越简单的数据,需要的cpu周期越少。例如,比较整数代价小于字符。
三、尽量避免Null——尽可能把字段定于为Not null。
Null列改为Not Null带来的性能提升很小,不是优先的优化措施。当然,如果对列进行索引,就尽量避免为空。
A、类型:
1、 整数
如果存储整数,可以使用这几种类型:
Tinyint,smallint,mediumint,int,bigint,分别需要8、16、24、32、64位的存储空间。
范围为-2(n-1)——2(n-1),N是存储空间位数。
Unsigned表示不允许负数。有符号和无符号类型占用的空间一样,性能也一样。
对整数定义宽度——例如int(10) ,这不会限制值的范围,只是规定交互工具显示的个数。对于存储,int(1) 和 int (20) 一样。
2、 实数
Mysql支持精确实数和非精确实数。
FLOAT和DOUBLE类型支持使用标准的浮点运算进行近似计算。
DECIMAL类型用于保存精确的小数。
比起DECIMAL,浮点型保存同样大小数值占用空间更少。FLOAT占用4个字节,DOUBLE占用8个,而且精度更高,范围更大。Mysql在内部对浮点使用DOUBLE进行计算。
由于需要额外的空间和计算开销,只在需要对小数进行精确计算的时候才用DECIMAL。
3、 字符串(针对innodb和myisam)
Varchar保存可变长度的字符串,能比固定长度类型占用更少的存储空间。(如在row_format=fixed下见的myisam表,每行使用固定长度空间,会造成浪费).
Varchar使用额外的1-2字节存储值的长度。<=255,使用1字节,否则2字节。
Varchar能节约空间,对性能有一定帮助。但是也有可能造成碎片或者分页,并且使用复杂的字符集也会有一些影响。另外5.0以上版本无论保存还是取值,Mysql都会保存varchar列末尾的空格。
char 是固定长度。在存储很短的字符串或者长度近似相同的字符串的时候很有用。
binary和varbinary ,用于保存二进制字符串。和传统字符串相似,但是它们保存的是自己,而不是字符。使用Binary要注意,mysql会使用空值(5.5.18版本)填充到需要的长度,并且取值的时候不会去掉。
root@test 12:06>create table test ( testcol binary(30) );
Query OK, 0 rows affected (0.04 sec)
root@test 12:07>insert into test values ('abcde');
Query OK, 1 row affected (0.01 sec)
root@test 12:11>select concat("'",testcol,"'") from test;
+----------------------------------+
| concat("'",testcol,"'") |
+----------------------------------+
| 'abcde ' |
+----------------------------------+
BOLB——二进制保存大量数据
TINYBLOB, BLOB,MEDIUMBLOB以及LONGBLOB
TEXT——以字符形式保存
TINYTEXT, TEXT,MEDIUMTEXT以及LONGTEXT。
INNODB在他们较大的时候会使用单独的“外部”存储区域来进行保存。
BLOB和TEXT的区别是BLOB保存的是二进制数据,没有字符集和排序规则。
BLOB和TEXT排序:不会按照字符串的完整长度排序,只是按照max_sort_length规定前N个字节排序。
ENUM可以存储65535个不同的字符串。会压缩到1-2个字节中。在内部都保存为整数,并且保留一份查找表来表示整数和字符的对应关系。麻烦的是字符串列表是固定的,添加和删除字符串需要alter table。
4、 日期和时间
DATETIME能保存大范围的值。使用8字节存储。YYYYMMDD HHMMSS格式
TIMESTAMP从1970-2038年。使用4字节存储。
如果插入时没有定义TIMESTAMP的值,会自动更新为当前时间。TIMESTAMP列默认是NOT NULL。
B、索引选择
1、整数:通常是索引的最佳选择,速度快,能auto_increment。
2、字符串类型:尽可能避免。占用空间多并且比整数类型慢。特别是在MYISAM表上,默认为字符串使用了压缩索引,使查找更缓慢。另外完全随机的字符串(如MD5(),UUID ()),产生的值会被任意的保存在很大的空间范围,会减慢insert 或者select。
3、特殊类型:时间戳和IP。
时间戳使用UNIX_TIMESTAMP()和FROM_UNIXTIME()函数转换。
IP可以使用INET_ATON()和INET_NTOA()函数转换。