Schema:是数据库对象的集合(好比用户创建了表,索引,视图,存储过程等对象,那么这些对象就构成了schema)mysql
应根据系统将要执行的查询语句来设计schema,每每须要权衡各类因素。sql
反范式的设计能够加快某些类型的查询(同时可能使另外一些类型的查询变慢)数据库
添加计数表和汇总表能够优化查询(这些表的维护成本可能会很高)缓存
选择数据类型的原则:服务器
1.小的好 :在能够正确存储数据的前提下,越小越好(好比能用tinyint就不用int,由于小的占用更少磁盘,内存和cpu缓存,处理时须要的CPU周期也更少)工具
2.简单好 :整型比字符型操做代价更低,使用MySQL内建类型(DATETIME和TIMESAMP)而不是字符串存储时间日期,用整型存储IP(TIMESAMP只使用DATETIME一半的存储空间,而且会根据时区变化,能自动更新,前者容许的时间范围小得多,有时这些特殊能力会成为障碍)性能
3.避免null:若查询中包含可为null的列更难优化,由于该列使得索引,索引统计和值比较都更复杂,会使用更多存储空间,而且须要特殊处理。当可为Null的列被索引时,每一个索引记录须要一个额外字节【在MyISAM里甚至还可能致使固定大小的索引变成可变大小的索引】优化
(一般把可为NULL的列改成NOT NULL带来的性能提高比较小,因此没有必要首先处理这种状况,除非肯定会致使问题。若计划在列上建索引,就应尽可能避免设计成可为NULL的列)spa
【INNODB使用单独的位(bit)存储NULL,因此对于稀疏数据(不少值为NULL,只有少数列为非NULL值)有很好的空间效率。但这点不适用于MYISAM】命令行
各类数据类型的注意点:
1.整数类型:
(1)有无符号类型使用相同的存储空间,并具备相同性能。
(2)MYSQL能够为整数类型指定宽度,例如INT(11),不过该宽度只是规定了MYSQL一些交互工具(例如MYSQL命令行客户端)的显示字符数,对于存储和计算来讲INT(1)和INT(20)并没有不一样
2.实数类型:
实数是带有小数部分的数字。但并不仅是为了存储小数部分,也可用DECIMAL存储比BIGINT还大的整数
(1)FLOAT 和 DOUBLE 支持浮点运算进行近似计算。
(2)DECIMAL 用于存储精确的小数。能够指定小数点先后所容许位数(会影响空间消耗)
【MYSQL5.0和更高版本支持精确计算,因为CPU不支持对DECIMAL的精确计算,MYSQL服务器自身实现了DECIMAL的高精度计算。(CPU支持原生浮点计算,因此浮点运算明显更快)】
【浮点类型在存储一样范围的值时,一般比DECIMAL使用更少空间。MYSQL使用 DOUBLE 做为内部浮点计算类型】
建议:
(1)只在须要对小数进行精确计算时使用 DECIMAL, 避免额外空间和计算开销;
(2)在数据量比较大时,用BIGINT代替DECIMAL,在存取时乘相应倍数便可
3.字符串类型:
下面描述假设存储引擎是InnoDB / MyISAM:
(1)varchar和char:
适合使用varchra:
1. 字符串列的最大长度比平均长度大不少
2. 列的更新不多
3. 使用相似utf-8的字符集,每一个字符都使用不一样字节存储
注:varchar(200)和varchar(5)存储'hello'开销是相同的,可是会耗更多内存(mysql会分配固定大小的内存块保存内部值,这样当使用内存临时表或利用磁盘临时表排序时会很糟糕)
适合使用char:
1. 很短的字符串(很是短的列char比varchar存储空间有优点,由于varchar存储长度还须要字节)
2. 同列全部值长度相近
3. 常常变动的数据