1. 首页 > DB2教程 > 正文

DB2教程FG061-DB2多租户架构设计实战

风哥教程参考DB2官方文档Multi-tenant Solutions、Schema Management、Security等内容,详细介绍多租户架构在DB2上的设计、实现与优化。更多视频教程www.fgedu.net.cn

目录大纲

Part01-多租户架构模式

1.1 多租户架构模式

DB2支持多种多租户架构模式:

  • 共享数据库、共享Schema:所有租户共享同一个Schema,通过租户ID字段隔离数据
  • 共享数据库、独立Schema:每个租户有独立的Schema
  • 独立数据库:每个租户有独立的数据库
  • 独立实例:每个租户有独立的DB2实例

1.2 各模式对比

模式 隔离程度 资源利用率 维护成本 适用场景
共享Schema 大量中小租户
独立Schema 中等规模租户
独立数据库 大型企业租户
独立实例 最高 最低 最高 特殊安全要求

Part02-共享Schema模式设计

2.1 表结构设计

# 租户表
CREATE TABLE TENANT (
TENANT_ID VARCHAR(32) NOT NULL,
TENANT_CODE VARCHAR(50) NOT NULL,
TENANT_NAME VARCHAR(200) NOT NULL,
TENANT_TYPE VARCHAR(20),
CONTACT_NAME VARCHAR(100),
CONTACT_PHONE VARCHAR(20),
CONTACT_EMAIL VARCHAR(100),
DB_SCHEMA VARCHAR(50),
MAX_USERS INTEGER,
MAX_STORAGE BIGINT,
EXPIRY_DATE DATE,
TENANT_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_TENANT PRIMARY KEY (TENANT_ID)
) ORGANIZE BY ROW;

# 共享用户表(带租户ID)
CREATE TABLE SHARED_USER (
USER_ID VARCHAR(32) NOT NULL,
TENANT_ID VARCHAR(32) NOT NULL,
USERNAME VARCHAR(100) NOT NULL,
PASSWORD VARCHAR(200) NOT NULL,
EMAIL VARCHAR(100),
PHONE VARCHAR(20),
USER_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_SHARED_USER PRIMARY KEY (USER_ID)
) ORGANIZE BY ROW;

# 共享订单表(带租户ID)
CREATE TABLE SHARED_ORDER (
ORDER_ID VARCHAR(32) NOT NULL,
TENANT_ID VARCHAR(32) NOT NULL,
ORDER_NO VARCHAR(50) NOT NULL,
USER_ID VARCHAR(32),
TOTAL_AMOUNT DECIMAL(18, 2),
ORDER_STATUS VARCHAR(20),
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_SHARED_ORDER PRIMARY KEY (ORDER_ID)
) ORGANIZE BY ROW;

# 创建索引(必须包含TENANT_ID)
CREATE UNIQUE INDEX IDX_SHARED_USER_TENANT ON SHARED_USER(TENANT_ID, USERNAME);
CREATE INDEX IDX_SHARED_ORDER_TENANT ON SHARED_ORDER(TENANT_ID, CREATE_TIME DESC);

# 创建视图(自动过滤租户数据)
CREATE VIEW V_SHARED_USER AS
SELECT * FROM SHARED_USER WHERE TENANT_ID = CURRENT CLIENT_ACCTNG;

CREATE VIEW V_SHARED_ORDER AS
SELECT * FROM SHARED_ORDER WHERE TENANT_ID = CURRENT CLIENT_ACCTNG;

2.2 连接设置

# 设置租户上下文
SET CLIENT_ACCTNG = ‘TENANT001’;

# 查询数据(通过视图自动过滤)
SELECT * FROM V_SHARED_USER;
SELECT * FROM V_SHARED_ORDER;

# 创建租户用户
CREATE USER tenant001_user PASSWORD ‘password’;
GRANT CONNECT ON DATABASE TO tenant001_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON SHARED_USER TO tenant001_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON SHARED_ORDER TO tenant001_user;
GRANT SELECT ON V_SHARED_USER TO tenant001_user;
GRANT SELECT ON V_SHARED_ORDER TO tenant001_user;

# 创建触发器(自动设置租户ID)
CREATE OR REPLACE TRIGGER TRG_SHARED_USER_TENANT
BEFORE INSERT ON SHARED_USER
REFERENCING NEW AS N
FOR EACH ROW
WHEN (N.TENANT_ID IS NULL)
SET N.TENANT_ID = CURRENT CLIENT_ACCTNG;

CREATE OR REPLACE TRIGGER TRG_SHARED_ORDER_TENANT
BEFORE INSERT ON SHARED_ORDER
REFERENCING NEW AS N
FOR EACH ROW
WHEN (N.TENANT_ID IS NULL)
SET N.TENANT_ID = CURRENT CLIENT_ACCTNG;

Part03-独立Schema模式设计

3.1 租户Schema创建

# 创建租户Schema
CREATE SCHEMA TENANT001;
CREATE SCHEMA TENANT002;
CREATE SCHEMA TENANT003;

# 在租户Schema中创建表
CREATE TABLE TENANT001.USER (
USER_ID VARCHAR(32) NOT NULL,
USERNAME VARCHAR(100) NOT NULL,
PASSWORD VARCHAR(200) NOT NULL,
EMAIL VARCHAR(100),
PHONE VARCHAR(20),
USER_STATUS VARCHAR(10) NOT NULL,
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_TENANT001_USER PRIMARY KEY (USER_ID)
) ORGANIZE BY ROW;

CREATE TABLE TENANT001.ORDER (
ORDER_ID VARCHAR(32) NOT NULL,
ORDER_NO VARCHAR(50) NOT NULL,
USER_ID VARCHAR(32),
TOTAL_AMOUNT DECIMAL(18, 2),
ORDER_STATUS VARCHAR(20),
CREATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
UPDATE_TIME TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP,
CONSTRAINT PK_TENANT001_ORDER PRIMARY KEY (ORDER_ID)
) ORGANIZE BY ROW;

# 为其他租户创建相同的表结构
CREATE TABLE TENANT002.USER LIKE TENANT001.USER;
CREATE TABLE TENANT002.ORDER LIKE TENANT001.ORDER;

CREATE TABLE TENANT003.USER LIKE TENANT001.USER;
CREATE TABLE TENANT003.ORDER LIKE TENANT001.ORDER;

# 创建租户用户并授权
CREATE USER tenant001_user PASSWORD ‘password’;
GRANT CONNECT ON DATABASE TO tenant001_user;
GRANT USE OF SCHEMA TENANT001 TO tenant001_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON TENANT001.USER TO tenant001_user;
GRANT SELECT, INSERT, UPDATE, DELETE ON TENANT001.ORDER TO tenant001_user;
ALTER USER tenant001_user SET CURRENT_SCHEMA = TENANT001;

# 创建存储过程:创建新租户
CREATE OR REPLACE PROCEDURE SP_CREATE_TENANT(
IN p_tenant_id VARCHAR(32),
IN p_tenant_name VARCHAR(200),
IN p_password VARCHAR(200),
OUT p_result_code VARCHAR(10),
OUT p_result_msg VARCHAR(200)
)
LANGUAGE SQL
BEGIN
DECLARE v_sql VARCHAR(2000);

SET p_result_code = ‘SUCCESS’;
SET p_result_msg = ‘租户创建成功’;

EXECUTE IMMEDIATE ‘CREATE SCHEMA ‘ || p_tenant_id;

EXECUTE IMMEDIATE ‘CREATE TABLE ‘ || p_tenant_id || ‘.USER LIKE TENANT001.USER’;
EXECUTE IMMEDIATE ‘CREATE TABLE ‘ || p_tenant_id || ‘.ORDER LIKE TENANT001.ORDER’;

EXECUTE IMMEDIATE ‘CREATE USER ‘ || p_tenant_id || ‘_user PASSWORD ”’ || p_password || ””;

EXECUTE IMMEDIATE ‘GRANT CONNECT ON DATABASE TO ‘ || p_tenant_id || ‘_user’;
EXECUTE IMMEDIATE ‘GRANT USE OF SCHEMA ‘ || p_tenant_id || ‘ TO ‘ || p_tenant_id || ‘_user’;
EXECUTE IMMEDIATE ‘GRANT SELECT, INSERT, UPDATE, DELETE ON ‘ || p_tenant_id || ‘.USER TO ‘ || p_tenant_id || ‘_user’;
EXECUTE IMMEDIATE ‘GRANT SELECT, INSERT, UPDATE, DELETE ON ‘ || p_tenant_id || ‘.ORDER TO ‘ || p_tenant_id || ‘_user’;
EXECUTE IMMEDIATE ‘ALTER USER ‘ || p_tenant_id || ‘_user SET CURRENT_SCHEMA = ‘ || p_tenant_id;

INSERT INTO TENANT (
TENANT_ID, TENANT_CODE, TENANT_NAME, DB_SCHEMA, TENANT_STATUS
) VALUES (
p_tenant_id, p_tenant_id, p_tenant_name, p_tenant_id, ‘ACTIVE’
);

END;

Part04-权限与隔离

4.1 权限管理

# 创建角色
CREATE ROLE TENANT_ADMIN;
CREATE ROLE TENANT_USER;

# 授权角色
GRANT SELECT, INSERT, UPDATE, DELETE ON SHARED_USER TO TENANT_USER;
GRANT SELECT, INSERT, UPDATE, DELETE ON SHARED_ORDER TO TENANT_USER;
GRANT SELECT ON TENANT TO TENANT_ADMIN;

# 授予角色给用户
GRANT TENANT_USER TO tenant001_user;
GRANT TENANT_ADMIN TO admin_user;

# 创建LBAC(基于标签的访问控制)
CREATE SECURITY POLICY TENANT_POLICY;

CREATE SECURITY LABEL TENANT_POLICY.TENANT001
COMPONENT TENANT ‘TENANT001’;

CREATE SECURITY LABEL TENANT_POLICY.TENANT002
COMPONENT TENANT ‘TENANT002’;

# 应用LBAC到表
ALTER TABLE SHARED_USER
ADD COLUMN TENANT_LABEL DB2SECURITYLABEL;

ALTER TABLE SHARED_USER
ADD SECURITY POLICY TENANT_POLICY;

# 授予用户安全标签
GRANT SECURITY LABEL TENANT_POLICY.TENANT001
TO USER tenant001_user FOR ALL ACCESS;

# 行权限控制(视图方式)
CREATE VIEW V_SHARED_USER_TENANT001 AS
SELECT * FROM SHARED_USER WHERE TENANT_ID = ‘TENANT001’
WITH CHECK OPTION;

CREATE VIEW V_SHARED_USER_TENANT002 AS
SELECT * FROM SHARED_USER WHERE TENANT_ID = ‘TENANT002’
WITH CHECK OPTION;

# 只授予视图权限,不授予基表权限
GRANT SELECT, INSERT, UPDATE, DELETE ON V_SHARED_USER_TENANT001 TO tenant001_user;

4.2 资源隔离

# 创建独立的表空间
CREATE TABLESPACE TENANT001_TS
PAGESIZE 8K
MANAGED BY DATABASE
USING (FILE ‘/db2data/tenant001/tenant001_ts.dms’ 100M);

CREATE TABLESPACE TENANT002_TS
PAGESIZE 8K
MANAGED BY DATABASE
USING (FILE ‘/db2data/tenant002/tenant002_ts.dms’ 100M);

# 在租户表空间中创建表
CREATE TABLE TENANT001.USER (

) IN TENANT001_TS;

# 配置WLM(工作负载管理器)
CREATE SERVICE CLASS TENANT001_SC
SOFT CPU SHARES 100
SOFT MEMORY SHARES 100;

CREATE SERVICE CLASS TENANT002_SC
SOFT CPU SHARES 100
SOFT MEMORY SHARES 100;

CREATE WORKLOAD TENANT001_WL
APPLNAME(‘TENANT001_APP’)
SERVICE CLASS TENANT001_SC;

CREATE WORKLOAD TENANT002_WL
APPLNAME(‘TENANT002_APP’)
SERVICE CLASS TENANT002_SC;

# 监控租户资源使用
SELECT
SUBSTR(TABSCHEMA, 1, 20) AS TABSCHEMA,
SUBSTR(TABNAME, 1, 30) AS TABNAME,
SUM(DATA_OBJECT_P_SIZE + INDEX_OBJECT_P_SIZE + LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE) AS TOTAL_SIZE_KB
FROM SYSIBMADM.ADMINTABINFO
WHERE TABSCHEMA LIKE ‘TENANT%’
GROUP BY TABSCHEMA, TABNAME
ORDER BY TABSCHEMA, TOTAL_SIZE_KB DESC;

SELECT
SUBSTR(WORKLOAD_NAME, 1, 20) AS WORKLOAD_NAME,
SUM(CPU_USAGE_TIME) AS TOTAL_CPU_TIME,
SUM(ROWS_READ) AS TOTAL_ROWS_READ,
SUM(ROWS_WRITTEN) AS TOTAL_ROWS_WRITTEN
FROM SYSIBMADM.WORKLOAD_OCCURRENCE_METRICS
WHERE WORKLOAD_NAME LIKE ‘TENANT%’
GROUP BY WORKLOAD_NAME;

Part05-风哥经验总结与分享

5.1 多租户设计要点

  • 根据租户规模选择合适的架构模式
  • 共享Schema模式要确保每个查询都带租户ID
  • 独立Schema模式要做好自动化Schema管理
  • 权限隔离要严格,防止跨租户数据访问
  • 资源隔离使用WLM和独立表空间
  • 监控每个租户的资源使用情况

5.2 性能优化建议

场景 优化方案
共享Schema查询 索引包含租户ID,使用视图简化查询
独立Schema 自动化创建,统一管理
资源隔离 WLM分配资源,独立表空间
备份恢复 按租户备份,支持单租户恢复

5.3 运维要点

  • 建立租户管理流程
  • 自动化租户创建和删除
  • 监控每个租户的资源使用
  • 定期备份,支持单租户恢复
  • 定期检查数据隔离是否有效
  • 建立租户扩容和缩容机制
更多视频教程www.fgedu.net.cn
学习交流加群风哥微信: itpux-com
风哥Oracle/MySQL/PostgreSQL/Greenplum/DB2/Redis等数据库培训课程,10年一线实战经验,企业级培训,真正掌握数据库核心技术!

本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html

联系我们

在线咨询:点击这里给我发消息

微信号:itpux-com

工作日:9:30-18:30,节假日休息