数据库切分与分区
查看表空间
查看oracle表空间和使用率:
select t.tablespace_name,round(SUM(byte/(1024*1024)),0) ts_size from dba_tablespace t,dba_data_files d
where t.tablespace_name=d.tablespace_name
group by t.tablespace_name;
查看数据库实例名称:
select instance_name from v$instance;
oracle表类型
表的功能:存储,管理数据的基本单位(二维表:有行和列组成)
1. 堆表:数据存储时,行时无序的,对他的访问采用全表扫描
2. 分区表 表>2G
3. 索引组织表(IOT)
4. 簇表
5. 临时表
6. 压缩表
7. 嵌套表
我们日常开发使用的分区分库的问题,其实都是基于OLTP和OLAP的业务前提,然后对数据做切分,列如垂直,水平切分。
OLTP和OLAP
在互联网时代,海量数据的存储与访问成为系统设计与使用的瓶颈问题,对海量数据的处理,按照使用场景,主要分为两种类型:联机事务处理(OLTP)和联机分析处理(OLAP)
OLTP:面向交易处理系统。其基本特征是原始数据可以立即传送到计算机进行处理,并在很短时间给出处理结果
OLAP:通过多维的方式对数据进行分析,查询和报表,可以同时同数据挖掘工具,统计分析工具配合使用,增强决策分析能力
数据切分
指通过某种特定的条件和规则,将我们放在同一个数据库中的数据分散到多个数据库(主机)上面,以达到分散单台设备负载。
数据的切分根据其切分规则的类型,可分为两种切分模式
垂直切分:按照不同的表来分到不同的数据库(主机)上
水平切分:根据表中的数据逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上
垂直切分就是规则简单,实施方便,适合各业务的耦合度非常低,互相影响小,业务逻辑非常清晰的系统。这种系统中,很容易做到将不同的业务模块所使用的表拆分到不同数据库中
水平切分比较复杂,因为需要将同一张表中不同数据拆分到不同的数据库中,对于应用程序而言,拆分规则本身就较按照表来拆分更为复杂,后期的数据维护也更复杂一些。
数据拆分优点和最佳实践方案
垂直拆分的优点:
业务逻辑清晰
可扩展性强
维护简单方便
水平拆分的优点:
拆分规则做的足够好,基本可以单库实现join
应用端改造较少,可以稍微轻松实现业务逻辑,但后期需求变更维护比较麻烦
不存在单库多数据,以及高并发下性能的瓶颈问题,提高系统稳定性和负载能力
垂直拆分就是最上层的业务逻辑拆分,比如电商的供应商,商品,库存,订单,网站等模块的业务流程非常清晰可见,最上层拆分即可。
水平拆分比如涉及到用户信息,订单信息,一般会设计多个系统,比如用户信息系统用户信息,根据用户等级划分到不同的库
数据拆分缺点和解决方案
无论水平还是垂直,都有缺点:
-
引入了分布式事务问题(针对不同场景案例,具体分析解决)
例如业务逻辑复杂时,在service层做多个切面,配置多个事务 例如数据量大且分析逻辑复杂时,使用缓冲表,缓存表等 例如要求实时性非常高且数据信息,业务逻辑简单单一,使用第三方数据通信组件(信息队列,zookeeper) -
跨节点join问题,跨节点合并,排序,分页等处理数据问题
通用方案是把数据组织好以后放到缓存中去,定时或者实时进行同步 如果要求实时性不是特别高,那么也可以使用中间库的手段去解决 -
多数据源管理问题
使用类似mycat的代理平台,管理多个数据源
分区表介绍
主要针对于大数据量,频繁查询数据等需求,有了表分区,我们可以对表进行区间的拆分和组织,提高查询效率。一般来讲表分区的一个区间数据最好不大于500W条,也就是说500w一个区间,根据业务需求和表分区的性能而定
range分区
hash分区
list分区
复合分区
间隔分区
system分区
range分区
range分区就是区域分区,按照定义的区域,进行划分。
语法:
create table tablename()
partition by range(field)(
partition p1 values less than(value),
partition p2 values less than(value),
partition p3 values less than(value),
);
查看分区情况: select * from user_tab_partitions;
查看分区数据: select * from table partition(p1);
修改分区:
添加:alter table tablename add partition p4 values less than(maxvalue)
删除:alter table tablename drop partition p4;
更新数据时操作不可以跨分区操作,会出现错误需要设置可移动的分区才能进行跨分区查询。
alter table tablename enable row movement;
分区索引
分区之后虽然可以提高查询效率,但也仅仅是提高了数据的范围,所以我们在有必要的情况下,需要建立分区索引,从而进一步提高效率。
分区索引大体分为:local,global
local:在每个分区建立索引
global:一种是在全局建立索引,这种方式分不分区都一样,一般不使用:还有一种就是自定义数据区间的索引,也叫做前缀索引,这个是非常有意义的,自定义区域时注意必须要maxvalue。
另外需要注意的是:在分区上建立索引必须是分区字段列。
local方式语法:creat index idxname on table(field) local;
查看分区索引:select * from user_ind_partitions;
global 自定义全局(前缀索引)方式语法
create index idxname on table(field) global
partition by range(field)(
partition p1 values less than(value),
partition p2 values less than(value),
partition p3 values less than(maxvalue)
);
global全局索引方式语句:create index idxname on table(field) global
hash分区
hash分区实现均匀的负载值分配,增加hash分区可以重新分布数据。
--1建立散列分区表
create table my_emp(
empno number,
ename varchar2(10);
)
partition by hash(empno){
partition p1,partition p2
};
--2查看分区表结构
select * from user_tab_partitions where table_name='my_emp';
--3查看分区数据
select * from my_emp partition(p1);
list分区
create table personcity(
id number,
name varchar2(10),
city varchar2(10)
)
partition by list(city)(
partition east values ('tianjin','dalian'),
partition west values ('xian'),
partition other values ('hebei'),
);
复合分区
把范围分区和散列分区结合或者范围分区和类别分区相结合
create table student(
sno number,
sname varchar2(10),
)
partition by range(sno)
subpartition by hash(sname)
subpartitions 4
(
partition p1 values less than(100),
partition p2 values less than(200),
partition p3 values less than(maxvalue),
);
select * from user_tab_partitons where table_name='student';
select * from user_tab_subpartitions where table_name='student';
间隔分区
Interval Partition是一种分区自动化的分区,可以指定时间间隔进行分区,Interval Partition实际上是由range分区引申,最终实现了range分区的自动化。
语法: creat table interval_sale (sid int , sdate timestamp) partition by range(sdate) interval(numtoyminterval(1,’month’))( partition p1 values less than (TIMESTAMP ‘2014-02-01 00:00:00.00’) )