何海棠,朱晓辉,陈苏蓉
(南通大学,江苏 南通 226007)
SaaS(Software-as-a-Service)类软件应用具有基于网络完成交付和使用、允许用户按需付费并在一定环境下对操作界面、数据结构等个性化定制的特点。SaaS应用所对应的数据库为多租户数据库,是多租户数据存储和个性化定义的保障。在设计时,需结合SaaS模式的特点,合理地平衡数据共享和数据隔离[1-2],既使不同租户的数据达到某种形式上的统一,促进数据的高效访问,又保证各租户数据的个性化和存取的独立性。
本文基于.NET环境,以SQL Server 2008为数据库管理软件,以面向中小型企业信息化管理的SaaS软件为例,在考虑数据共享和数据隔离的基础上,围绕多租户数据的存储、子用户与租户的对应、子用户权限的管理、租户数据的扩展等几个方面对SaaS模式下的多租户数据库进行研究。
SaaS模式下的多租户数据库按数据的存储形式可分为独立数据库和共享数据库。独立数据库和租户间为1∶1关系,每个租户在自己的独立数据库中进行数据存取。共享数据库和租户间为1∶n关系,所有的租户共用一个数据库,不同租户在同一个数据库中进行数据存取;根据共享数据库中的租户是否使用相同的表集,还可分为共享SCHEMA和独立SCHEMA 两种架构[2-4]。
无论采用哪种数据库存储方案,均需解决数据库和租户间的对应问题。该问题的解决可通过构建存储租户基本信息的注册租户表解决,在该表中设置companyID字段和connectionString字段以体现租户和数据库间的对应。companyID用于标识租户,为保证其惟一性及可管理性,可设置其为int型且具有IDENTITY属性,每增加一个租户,自动按规则产生新值填充。connectionString字段以字符串形式存储与companyID对应的数据库信息,形如“server=ServerNo1;uid=sa;pwd=123456;database=dbID;”,提供数据库服务器名、数据库名、登陆方式、登陆名、登陆密码等;该字符串中server和database的不同取值可体现是共享数据库还是独立数据库。
SaaS模式下的数据库所有者为不同租户(本文只考虑租户为中小型企业),同一租户往往又存在多个子用户,在解决完数据库和租户间的对应问题后,需考虑如何实现子用户和租户间的对应,其本质为解决子用户和租户数据库间的对应。
该问题的解决基础是构建注册用户表,存储employeeID(子用户 ID)、loginName(子用户名)、loginPwd(密码)等信息。子用户在登陆时需提供companyID、employeeID、loginPwd,系统据此查看注册租户表和注册用户表以完成子用户和租户数据库间的对应。
注册用户表可存储在租户数据库中。独立数据库方案下,一个租户对应一张注册用户表;共享数据库共享SCHEMA方案下,多个租户对应一张注册用户表,且该表中需添加租户ID字段用以标识该用户的归属;共享数据库独立 SCHEMA方案下,每个SCHEMA中存储一张注册用户表,无需额外添加租户ID字段。
不同租户及其子用户对多租户数据库通常存在不同的访问需求。为保证租户数据的安全,需划分对数据库的不同操作(细化到对表、字段的存取),并将其对应到不同的用户,即为不同用户设置不同的数据库访问权限。另外,SaaS模式下,软件应用的一个重要特点是可配置性,租户可按需选择功能模块,在设计时,与数据库存取相关的功能模块可与数据库访问权限结合起来,采用角色管理的方法实现其可配置性。可行的方法步骤如下:
(1)构建功能模块描述表,设置functionID(int)字段,用于标识每个功能模块。
(2)构建角色描述表,设置roleID(int)和functionIDs(char)字段,roleID用于标识每个角色(角色的划分可结合企业的不同业务岗位,如会计、销售员、仓库管理员等),functionIDs用于存储每个roleID对应的functionID集合。
实际基于.NET环境进行软件实现时,可考虑将模块功能的展现对应到网页、模块功能的调用对应到多级菜单的菜单项,将构建功能模块描述表改为构建菜单信息描述表,在该表中设置menuID(int)和menuURL(nvarchar)字段,menuID用于标识每个菜单项,menuURL用于存储与模块功能展现对应的网页地址;将角色描述表中的functionIDs字段改为menuIDs字段,存储每个roleID对应的menuID集合。
(3)在注册用户表中添加roleID字段,将用户与角色联系。
传统的多租户数据库在设计时基于所有租户数据需求的并集进行,所有租户的数据结构完全相同且固定,容易造成数据冗余,不符合SaaS模式下允许租户个性化数据的特点。目前,SaaS模式下的多租户数据库在设计时较多地采用固定扩展或定制扩展[5-7]的方式。
固定扩展方式是以为表预留字段的方式提供扩展,其可扩展性受限于预留字段的数目和预留字段的类型,且无法保证预留字段的最佳利用率。因此,笔者在研究时基于共享数据库共享SCHEMA采用定制扩展的方式为租户提供扩展,其设计思路基于单个标准数据库表(Standard)与扩展数据表(Extension)之间的通用关系(如图1所示),具体实现时考虑将共享数据库中所有扩展数据统一存储管理,涉及到 Tb_Table、Tb_ExBase、Tb_Extension 三张表(如图2),说明如下:
(1)Tb_Table存储存在扩展需求的companyID、tableID(表)及 tableName(表名)。
(2)Tb_ExBase存储所有扩展字段的基本属性,ID为扩展字段的唯一标识,fieldID为该字段在特定租户的特定表中的唯一标识。companyID、tableID、fieldID、fieldEN(字段英文名,fieldCH用于显示,为字段中文名)的组合不允许重复。
Tb_Table和Tb_ExBase基于companyID+tableID字段存在1∶n联系。
(3)Tb_Extension存储扩展字段的值,recordID为tableID指定表中的具有扩展字段值的实体编号,recordID的存在要求共享数据库中所有存在潜在扩展需求的表均具有recordID字段,若实体有扩展数据,则用自增且保持唯一的值对其填充,否则为NULL。tableID、recordID、fieldID的组合不允许重复。
某租户(已具有companyID)个性化数据的操作原理如下:
(1)添加扩展字段:根据当前需扩展对象(表)名在Tb_Table中检索tablename,若存在,则获取tableID,否则自动生成tableID,并向Tb_table中填充companyID和tablename;根据tableID、按字段扩展顺序产生的fieldID,将扩展字段的相关属性填充到Tb_ExBase表。
(2)删除扩展字段:根据租户界面操作确定companyID、tableID、fieldID,在 tableID 指定表中获取companyID对应的实体的recordID集,根据tableID、recordID、fieldID的组合将Tb_Extension中对应的记录全部删除,并在Tb_ExBase中删除companyID、tableID、fieldID组合确定的记录。
(3)添加扩展字段值:根据用户界面操作确定tableID、fieldID、value,在 tableID 中为当前实体产生recordID,在Tb_Extension添加记录。
(4)修改扩展字段值:根据用户界面操作确定tableID、fieldID、value,在 tableID 中检索当前实体的recordID,在Tb_Extension中修改记录。
(5)显示扩展字段值:获取当前实体的tableID、recordID,若recordID值不为NULL,则根据该值及tableID在Tb_Extension获取fieldID和value值,利用companyID、tableID、fieldID的组合在Tb_ExBase中获取fieldCH、dataType,根据dataType选用合适的界面元素在界面上将value进行显示。
(6)删除扩展字段值:部分删除则参照(4)的操作;若全部删除,则在删除Tb_Extension中tableID和recordID对应的记录后,还需将tableID指定表中对关的recordID的值修改为NULL。
SaaS模式下,软件服务商基于网络采用一个应用实例,或基于同一代码库的多个同构应用实例,为多个中小型企业同时提供诸如CRM、ERP等企业信息化服务,其服务的支持基础为多租户数据库。本文对SaaS模式下的多租户数据库设计过程中不可避免的数据存储、权限管理、数据扩展等问题进行了讨论,并给出了具体的解决思路和实现方法。在今后的研究中,还需基于多租户特点对加快扩展数据的查询、共享数据库形式下数据的备份和恢复等问题作进一步的研究,以更好地为SaaS模式下的软件提供支持。
[1]Frederick Chong and Gianpaolo Carraro.Architecture Strategies for Catching the Long Tail[J/OL].http://msdn.microsoft.com/en - us/library/aa479069.2006.
[2]Frederick Chong,Gianpaolo Carraro,and Roger Wolter.Multi- Tenant Data Architecture[J/OL].http://msdn.microsoft.com/en - us/library/aa479086.2006.
[3]Robert Vieira.SQLServer2008高级程序设计[M].杨华,腾灵灵(译).北京:清华大学出版社,2010.
[4]查俊,温浩宇,杨朝君.SaaS数据层方案比较研究[J].情报杂志,2010,(29).
[5]昌中作,徐悦,戴钢.基于SaaS模式公共服务平台多用户
数据结构的研究[J].计算机系统应用,2008,(2):7 -11.[6]孔兰菊,李庆忠,史玉良,等.面向SaaS应用基于键值对
模式的多租户索引研究[J].计算机学报,2010,33(12):2239-2246.
[7]凌永红,周新.SaaS模式下数据扩展性的设计与实现[J].
计算机与数字工程,2009,37(12):76 -79,187.