1.对于InnoDB表,自动增长列必须是索引。如果是组合索引,也必须是组合索引的第一列
2. 对于 MyISAM 表,自动增长列可以是组合索引的其他列,这样插入记录后,自动增长列是按照组合索引的前面几列进行排序后递增的。
3. MySQL支持外键的存储引擎只有InnoDB,在创建外键的时候,要求父表必须有对应的索引,子表在创建外键的时候也会自动创建对应的索引。
4. InnoDB存储表和索引有以下两种方式。
- 使用共享表空间存储
- 使用共享表空间存储
如何选择合适的存储引擎
- MyISAM:以读操作和插入操作为主,不涉及到事务的并发。MyISAM是在Web、数据仓储和其他应用环境下最常使用的存储引擎之一。
- InnoDB:用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询以外,还包括很多的更新、删除操作,那么InnoDB存储引擎应该是比较合适的选择。InnoDB存储引擎除了有效地降低由于删除和更新导致的锁定,还可以确保事务的完整提交(Commit)和回滚(Rollback),对于类似计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB都是合适的选择。
- MEMORY:将所有数据保存在 RAM 中,在需要快速定位记录和其他类似数据的环境下,可提供极快的访问。MEMORY 的缺陷是对表的大小有限制,太大的表无法缓存在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY表通常用于更新不太频繁的小表,用以快速得到访问结果。
- MERGE:用于将一系列等同的MyISAM表以逻辑方式组合在一起,并作为一个对象引用它们。MERGE表的优点在于可以突破对单个MyISAM表大小的限制,并且通过将不同的表分布在多个磁盘上,可以有效地改善MERGE表的访问效率。这对于诸如数据仓储等VLDB环境十分适合。
如何选择合适的数据类型
CHAR 与VARCHAR
二者都是用来存储字符串,但是他们保存和检索的方式不一样。char是固定长度的字符类型。varchar是可变长度的字符类型。
mysql> CREATE TABLE vc (v VARCHAR(4), c CHAR(4));
mysql> INSERT INTO vc VALUES ('ab ', 'ab ')
由于CHAR是固定长度的,所以它的处理速度比VARCHAR快得多,但是其缺点是浪费存储空间,程序需要对行尾空格进行处理,所以对于那些长度变化不大并且对查询速度有较高要求的数据可以考虑使用CHAR类型来存储。
InnoDB存储引擎:建议使用VARCHAR类型。对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。
因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。
TEXT与BLOB
-
BLOB和TEXT值会引起一些性能问题,特别是在执行了大量的删除操作时。
删除操作会在数据表中留下很大的“空洞”,以后填入这些“空洞”的记录在插入的性能上会有影响。为了提高性能,建议定期使用OPTIMIZE TABLE功能对这类表进行碎片整理,避免因为“空洞”导致性能问题。
mysql> OPTIMIZE TABLE t;
-
以使用合成的(Synthetic)索引来提高大文本字段(BLOB或TEXT)的查询性能。
简单来说,合成索引就是根据大文本字段的内容建立一个散列值,并把这个值存储在单独的数据列中,接下来就可以通过检索散列值找到数据行了。
如下:在创建表之后,插入数据时,中hash_value用来存放context列的MD5散列值。mysql> create table t (id varchar(100),context blob,hash_value varchar(40)); insert into t values(1,repeat('beijing',2),md5(context));
以上只能用于精确查询。
-
避免检索text和blob类型的字段。
-
把blob列和text放到单独的表中。
浮点数和定点数
浮点数一般用于表示含有小数部分的数值。当一个字段被定义为浮点类型后,如果插入数据的精度超过该列定义的实际精度,则插入值会被四舍五入到实际定义的精度值,然后插入,四舍五入的过程不会报错。在MySQL中float、double(或real)用来表示浮点数。
定点数不同于浮点数,定点数实际上是以字符串形式存放的,所以定点数可以更精确地保存数据。如果实际插入的数值精度大于实际定义的精度,则 MySQL 会进行警告(默认的SQLMode下),但是数据按照实际精度四舍五入后插入;如果SQLMode是在TRADITIONAL (传统模式)下,则系统会直接报错,导致数据无法插入。在MySQL中,decimal(或numberic)用来表示定点数。
在今后关于浮点数和定点数的应用中,用户要考虑到以下几个原则:
-
浮点数存在误差问题;
-
对货币等对精度敏感的数据,应该用定点数表示或存储;
-
在编程中,如果用到浮点数,要特别注意误差问题,并尽量避免做浮点数比较;
-
要注意浮点数中一些特殊值的处理。
日期类型选择
-
MySQL提供的常用日期类型有DATE、TIME 、DATETIME、TIMESTAMP。
-
根据实际需要选择能够满足应用的最小存储的日期类型。如果应用只需要记录“年份”,那么用1个字节来存储的YEAR类型完全可以满足,而不需要用4个字节来存储的DATE类型。这样不仅仅能节约存储,更能够提高表的操作效率。
-
如果要记录年月日时分秒,并且记录的年份比较久远,那么最好使用 DATETIME,而不要使用TIMESTAMP。因为TIMESTAMP表示的日期范围比DATETIME要短得多。
-
如果记录的日期需要让不同时区的用户使用,那么最好使用TIMESTAMP,因为日期类型中只有它能够和实际时区相对应。
总结:
-
对于字符类型,要根据存储引擎来进行相应的选择。
-
对精度要求较高的应用中,建议使用定点数来存储数值,以保证结果的准确性。
-
对含有 TEXT 和 BLOB 字段的表,如果经常做删除和修改记录的操作要定时执行OPTIMIZE TABLE功能对表进行碎片整理。
-
日期类型要根据实际需要选择能够满足应用的最小存储的日期类型。