oracle实例、schema,以及多租户方案

写这篇博客的起源,是前几天讨论我们的一个应用如何实现多租户,引发一些思考,在此记录一下

场景是这样的,我们的应用是企业应用,所以与互联网应用有先天的区别。互联网应用,比如淘宝、新浪微博等,面向的是终端用户,天然必须是多用户共享一个系统

而我们的应用面向的是项目,目前是单个应用支撑单个项目。如果需要支撑多个项目,会用部署多个应用的方式来解决

但是随着接入项目数量增多,一个项目必须部署一套应用,硬件成本也随之上升,最终就给一线成本带来压力。为了降低项目成本,产品规划开始往多租户发展,即单个应用服务多个项目



ORACLE的基本结构如上图:

数据库:本质上就是文件的集合,RDBMS的各种表,最终是以数据文件(.ora等)的方式保存的

实例:进程和内存的集合。oracle客户端不能直接操作数据库的数据文件,而是通过实例来操作。实际上oracle client和实例,构成了C/S的关系

schema:schema是oracle特有的概念,和user是一一对应的。表和索引等,不会直接挂载在数据库下,而是挂载在不同的schema下

表:就是应用程序最经常打交道的数据库表

打一个比方来说明:

数据库就是一座公寓,所有的东西都在公寓里面。然后实例就是这座公寓的管理处,外面的人不能直接跟公寓打交道,需要通过管理处来打交道。一个实例只能加载一个数据库,但是在RAC环境下,一个数据库可以被多个实例同时加载

公寓里有很多房间,这些房间就是schema。每个房间都有一个主人,这个主人就是user。主人和房间是一一对应的。所有的表、索引等,都是房间里的家具,不属于公寓,而是属于具体的房间

schema.table,才是一张表的唯一标识。有点像JAVA里的类标识,一个类名并不能唯一标识一个class,而是跟ClassLoader组合在一起,ClassLoader.Class才能唯一标识一个类。这里ClassLoader就相当于schema,Class就相当于table

接下来,我们的产品要实现多租户,就一定涉及到数据隔离的问题,也就不能脱离上面的oracle模型(假定不更换数据库)

现在就有2种方案

第一种方案,是将不同的项目数据,放到不同的schema下,而业务表则是一样的复制多份



第二种方案,是所有项目的数据,放到同一个表里,通过project_id字段进行区分



这2种方案各有利弊:

第一种方案,相当于从一开始就进行了表拆分,不同项目的数据放在不同的表里,数据库的压力比较小。但是这要求应用解决数据库路由的问题,针对不同项目的查询请求,能够自动路由到不同的表中操作。传统的ORM方案,基本上很难奏效。因为ORM中的实体类,与数据库表是一一对应的(静态配置了schema和table),无法适应这种场景。或者说hibernate等ORM框架,针对这类场景,存在先天不足

第二种方案,表相对固定,在DAL层不需要做特别的处理,传统的ORM方案即可满足。但是相对的,随着接入项目数增加,数据库的压力会很大,因为所有项目的数据都在一张表里,数据库IO会成为应用的瓶颈。最终还是会走到表拆分的这一步,照样会面临第一种方案的问题,即如何实现数据库访问的路由

猜你喜欢

转载自kyfxbl.iteye.com/blog/1896237