MySQL之数据库结构优化
1.选择合适的数据类型
一、选择能够存下数据类型最小的数据类型
二、可以使用简单的数据类型。int 要比varchar在MySQL处理上简单
三、尽可能的使用not null 定义字段
四、尽量少用txt类型,非用不可时考虑分表。
五、举例:
使用int类型存储日期时间,利用FROM_UNIXTIME(),UNIX_TIMESEAMP()两个函数转换
mysql> SELECT FROM_UNIXTIME(1234567890, '%Y-%m-%d %H:%i:%S'); +------------------------------------------------+ | FROM_UNIXTIME(1234567890, '%Y-%m-%d %H:%i:%S') | +------------------------------------------------+ | 2009-02-14 07:31:30 | +------------------------------------------------+ 1 row in set (0.00 sec) mysql> SELECT UNIX_TIMESTAMP(2009-02-14 07:31:30); ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use n ear '07:31:30)' at line 1 mysql> SELECT UNIX_TIMESTAMP('2009-02-14 07:31:30'); +---------------------------------------+ | UNIX_TIMESTAMP('2009-02-14 07:31:30') | +---------------------------------------+ | 1234567890 | +---------------------------------------+ 1 row in set (0.00 sec) mysql>
使用bigint存储IP地址,利用INET_ATON(),INET_NTOA()两个函数转换
mysql> select inet_aton('192.168.1.200'); +----------------------------+ | inet_aton('192.168.1.200') | +----------------------------+ | 3232235976 | +----------------------------+ 1 row in set (0.00 sec) mysql> select inet_ntoa(3232235976); +-----------------------+ | inet_ntoa(3232235976) | +-----------------------+ | 192.168.1.200 | +-----------------------+ 1 row in set (0.00 sec)
2.表的范式优化
一、标的范式化设计(符合三范式要求)
a:第一范式,每个属性不能拆分。
b:第二范式,含有主键。
c:不能存在非关键字的传递依赖,都必须依赖主键。
范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦。
二、表的反范式化
表的反范式是指为了查询效率的考虑吧原来符合第三范式的表适当的增加冗余,已达到优化查询的目的。反范式是一种以空间换取时间的操作。
举例:如我们现在要对一个 学校的课程表进行操作,现在有两张表,一张是学生信息student(a_id,a_name,a_adress,b_id)表,一张是课程表 subject(b_id,b_subject),现在我们需要一个这样的信息,把选择每个课程的的课程名称和学生姓名输出来:
SQL语句为:select B.b_id,B.b_subject,A_a_name from student A ,subject B;
当上面的数据量不多时,我们这样去查询没有问题;当我们的两张表的数据都是在百万级的时候,我们去查上面的信息, 问题出现了,这个查询动不动就是几百毫秒, 甚至更慢,这样的查询效率根本不能满足我们对于网页速度的要求。我们可以这样设计:在课程表里面添加冗余字段——学生姓名,这 样 我们就可以通过下面的查询 达到同样的目的:
SQL语句为:select b_id,b_subject,a_name from subject B;
这样的执行结果会在效率上面优化很多。可以通过SQL查询试试看。
3.表的垂直拆分
标的垂直拆分就是指把含有很多列的表拆分为多个表,这样就可以解决表的宽度问题。拆分原则如下:
一、不太常用的字段放到一个表中
二、把大字段独立的放到一个表中
三、把经常使用的字段放到一个表中
4.表的水平拆分
表的水平拆分是为了解决表中数据量大的问题,水平拆分的表每一个表结构都是完全一致的。
一、根据业务属性拆表
用业务属性拆表,业务关系复杂的情况下,如果要根据其他条件查询,其他的条件都必须和这个属性关联起来,查询条件必须带有这个属性。这种分表方式的算法 大致是取模,hash,md5等。
二、根据时间拆表
当表的关系比较复杂时,无法根据某个维度进行分表。但是有明显的时效性。
三、根据自增长ID拆表
这种分割法不是取模分,而是每张表存指定量的数据。如果数据量到了,就存放到新表中。这样可以完全控制每张表的数据量。关系非常简单并且有时效性的情况下 可以用。
四、数据迁移的方式
当一些很久之前的数据,很少再查询。比如员工工资表,我们可以只存今年的工资情况。而历史数据我们可以迁移到一张salary_old表中,保证数据不会丢失。但 也可以用来查询。