大数据的优化方式

一,前言

当数据量太大时,单张表的访问会造成严重的性能问题,这个时候需要将数据分开存储,以降低对单张表的访问压力。分开逻辑无外乎如下两种:

1,在同一个数据库实例上分开存储,这种方式英文叫做partition,意味分区
2,分开存储在不同实例上,甚至多太服务器上 ,这种英文叫做shared,意为分片

二,分区(Partition)

对一张表的分区有两种方式,如下:

  • 横向分区(Horizontal partitioning)
  • 纵向分区(Vertical partitioning)

2.1横向分区

定义:按行划分,将不同的行记录存储在不同的表或物理分区上

举例:将全国所有人员信息按省份分表存储,如四川人存储在一张表,广东人存储一张表。

oracle貌似可以指定对单张表进行分区存储,而不一定非要逻辑上创建不同的表,如下:

create table data (
    id integer primary key, 
    status char(1), 
    data1 varchar2(10), 
    data2 varchar2(10) )
    partition by list (status) ( 
       partition active_data values ( 'A' ),
       partition other_data values(default) 
    );

优点:单张表的记录数减小,能够获得更好的查询效率。

值得注意的是,要想获得全局结果集,可以使用一个view来查询两张表

2.2纵向区分

定义:按列来划分划分表,将不同列划分到不同的表或物理分区

举例:一个人的信息可能包含很多属性,比如姓名,年龄,性别,升高,体重等。假设我们在系统登录后,只简单显示用户的姓名,和性别。且大多数对于用户信息表的查询都只是为了获取这两个信息,那么可以纵向拆分,生成两个表,将用户姓名和年龄做成一张表,将升高,体重做成另外一张表,这两张表通过外键关联。如下:

create table data (
    id integer primary key, 
    status char(1) not null, 
    data1 varchar2(10) not null, 
    data2 varchar2(10) not null);
One way to partition data vertically: Split it as follows:

create table data_main (
    id integer primary key,
    status char(1) not null,
    data1 varchar2(10) not null );

create table data_rarely_used (
    id integer primary key,
    data2 varchar2(10) not null,
    foreign key (id) references data_main (id) );

优点:通过这种方式降低了单张表的数据存储容量,将热点数据拆分出来后,获得较高的访问性能

缺点:查询整体信息需要使用外键关联,这会增加性能开销

三,分片(Shard )

分片实际上是横向分区的一种,只是分片其数据物理存储在多个实例,甚至多个server上。

优点:减小了单张表的数据存储量,从而减小了索引的大小,能够获得很好的访问性能

缺点

  • 严重依赖server间的通信
  • 如果应用层访问的数据存放在多个shared上,将是个麻烦事
  • 多数据节点数据的持久性和一致性将是个问题

3,1支持分片的数据库

诸多nosql数据库,比如mongodb,Apache HBase。传统关系数据库中,mysql也支持,MySQL Cluster