kingbase教程FG143-金仓数据库多租户架构设计与实现
本文档详细介绍了金仓数据库多租户架构的设计与实现,包括多租户的概念、架构类型、设计原则、实施步骤等内容。风哥教程参考金仓官方文档多租户管理、安全管理等内容,适合DBA人员和应用开发人员实施数据库多租户架构。
Part01-基础概念与理论知识
1.1 多租户概述
多租户是一种软件架构模式,允许单个软件实例同时服务多个租户(客户),每个租户的数据相互隔离,逻辑上独立。多租户架构可以提高资源利用率,降低运维成本,便于集中管理。
多租户的优势:
# 共享数据库共享表策略
1. 表结构设计
– 在每个表中添加租户ID字段
– 租户ID作为主键的一部分或索引
2. 数据访问控制
– 在应用层添加租户ID过滤条件
– 使用视图或存储过程限制数据访问
3. 性能优化
– 在租户ID字段上创建索引
– 分区表按租户ID分区
– 使用缓存减少数据库访问
# 共享数据库独立表策略
1. 表命名规则
– 表名格式:{租户ID}_{表名}
– 例如:tenant1_user, tenant2_user
2. 数据访问控制
– 在应用层根据租户ID选择对应的表
– 使用动态SQL生成表名
3. 管理维护
– 自动生成表结构脚本
– 批量执行维护操作
– 监控表空间使用情况
# 独立数据库策略
1. 数据库管理
– 为每个租户创建独立的数据库
– 数据库命名格式:{租户ID}_db
2. 连接管理
– 为每个租户创建独立的数据库用户
– 使用连接池管理数据库连接
3. 资源隔离
– 限制每个数据库的资源使用
– 监控每个数据库的性能指标
– 实施数据库级别的备份和恢复
- 资源共享:多个租户共享同一套基础设施,提高资源利用率
- 成本降低:减少硬件和软件的投入,降低运维成本
- 集中管理:集中管理多个租户,简化运维管理
- 快速部署:新租户可以快速部署,缩短上线时间
- 统一升级:统一升级软件版本,确保所有租户使用最新功能
1.2 多租户架构类型
1.2.1 共享数据库共享表方案
- 概念:多个租户共享同一个数据库和同一个表,通过租户ID字段区分不同租户的数据
- 优点:资源利用率高,管理简单,成本低
- 缺点:数据隔离性差,性能可能受影响,扩展性有限
- 适用场景:租户数量多,数据量小,对隔离性要求不高的场景
1.2.2 共享数据库独立表方案
- 概念:多个租户共享同一个数据库,但每个租户有独立的表,表名中包含租户ID
- 优点:数据隔离性较好,性能较高,管理相对简单
- 缺点:资源利用率相对较低,表数量可能较多
- 适用场景:租户数量中等,数据量较大,对隔离性有一定要求的场景,风哥提示:
1.2.3 独立数据库方案
- 概念:每个租户有独立的数据库,完全隔离
- 优点:数据隔离性最好,性能最高,安全性强
- 缺点:资源利用率低,管理复杂,成本高
- 适用场景:租户数量少,数据量大,对隔离性和安全性要求高的场景
1.3 多租户应用场景
1.3.1 SaaS应用
- 场景:软件即服务(SaaS)应用,如CRM、ERP、HR系统等
- 特点:多租户共享同一套应用,数据相互隔离
- 优势:降低部署成本,提高管理效率
1.3.2 企业内部系统
- 场景:企业内部的多部门系统,如财务系统、项目管理系统等
- 特点:不同部门作为不同租户,数据相互隔离
- 优势:集中管理,数据安全,简化维护
1.3.3 云服务平台
- 场景:云服务平台,如数据库服务、存储服务等
- 特点:多个用户共享云服务资源,数据相互隔离
- 优势:资源利用率高,按需付费,灵活扩展
Part02-生产环境规划与建议
2.1 多租户架构设计原则
2.1.1 数据隔离原则
- 逻辑隔离:通过租户ID等字段区分不同租户的数据
- 物理隔离:通过独立的数据库或表实现数据隔离
- 权限隔离:通过权限控制确保租户只能访问自己的数据
- 网络隔离:通过网络分区确保租户数据的安全传输
2.1.2 性能原则
- 资源分配:合理分配计算、存储和网络资源,学习交流加群风哥微信: itpux-com
- 查询优化:优化查询语句,提高查询性能
- 缓存策略:使用缓存,减少数据库访问
- 负载均衡:均衡分配租户的请求,避免单点压力
2.1.3 可扩展性原则
- 水平扩展:支持通过增加节点来扩展系统容量
- 垂直扩展:支持通过增加资源来提升单个节点的性能
- 弹性伸缩:根据负载自动调整资源分配
- 模块化设计:采用模块化设计,便于功能扩展
2.1.4 可维护性原则
- 统一管理:集中管理所有租户的配置和监控
- 自动化运维:实现自动化的部署、监控和故障处理
- 日志管理:统一管理所有租户的日志,便于问题排查
- 备份与恢复:定期备份数据,确保数据安全
2.2 多租户数据隔离策略
2.2.1 共享数据库共享表策略
# 共享数据库共享表策略
1. 表结构设计
– 在每个表中添加租户ID字段
– 租户ID作为主键的一部分或索引
2. 数据访问控制
– 在应用层添加租户ID过滤条件
– 使用视图或存储过程限制数据访问
3. 性能优化
– 在租户ID字段上创建索引
– 分区表按租户ID分区
– 使用缓存减少数据库访问
2.2.2 共享数据库独立表策略
# 共享数据库独立表策略
1. 表命名规则
– 表名格式:{租户ID}_{表名}
– 例如:tenant1_user, tenant2_user
2. 数据访问控制
– 在应用层根据租户ID选择对应的表
– 使用动态SQL生成表名
3. 管理维护
– 自动生成表结构脚本
– 批量执行维护操作
– 监控表空间使用情况
2.2.3 独立数据库策略
# 独立数据库策略
1. 数据库管理
– 为每个租户创建独立的数据库
– 数据库命名格式:{租户ID}_db
2. 连接管理
– 为每个租户创建独立的数据库用户
– 使用连接池管理数据库连接
3. 资源隔离
– 限制每个数据库的资源使用
– 监控每个数据库的性能指标
– 实施数据库级别的备份和恢复
2.3 性能与安全考虑
2.3.1 性能优化
性能优化建议:
- 索引优化:在租户ID字段上创建索引,提高查询性能
- 分区策略:使用分区表,按租户ID或时间分区
- 缓存策略:使用缓存,减少数据库访问
- 连接池:使用连接池,优化数据库连接管理
- 查询优化:优化SQL语句,减少全表扫描
2.3.2 安全措施
安全措施建议:
- 访问控制:实施严格的访问控制,确保租户只能访问自己的数据,学习交流加群风哥QQ113257174
- 数据加密:对敏感数据进行加密存储
- 审计日志:记录所有操作,便于安全审计
- 网络安全:使用SSL/TLS加密数据传输
- 备份与恢复:定期备份数据,确保数据安全
Part03-生产环境项目实施方案
3.1 多租户架构实施步骤
3.1.1 共享数据库共享表方案实施
# 共享数据库共享表方案实施步骤
## 1. 设计表结构
# 创建用户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL,
UNIQUE (tenant_id, username)
);”
# 创建订单表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id, user_id) REFERENCES fgedu_user (tenant_id, id)
);”
# 创建索引
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_user_tenant_id ON fgedu_user (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_order_tenant_id ON fgedu_order (tenant_id);”
## 2. 插入测试数据
# 插入租户1的数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_user (tenant_id, username, email, password, create_time) VALUES
(1, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now()),
(1, ‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant1.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order (tenant_id, user_id, order_date, total_amount, status, create_time) VALUES
(1, 1, ‘2024-01-01’, 100.00, ‘completed’, now()),
(1, 2, ‘2024-01-02’, 200.00, ‘pending’, now());”
# 插入租户2的数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_user (tenant_id, username, email, password, create_time) VALUES
(2, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password1’, now()),
(2, ‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant2.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order (tenant_id, user_id, order_date, total_amount, status, create_time) VALUES
(2, 3, ‘2024-01-01’, 150.00, ‘completed’, now()),
(2, 4, ‘2024-01-02’, 250.00, ‘pending’, now());”
## 3. 验证数据隔离
# 查询租户1的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 1;”
# 查询租户2的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 2;”
# 验证跨租户数据隔离
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 1 AND username = ‘fgedu_user1’;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 2 AND username = ‘fgedu_user1’;”
## 1. 设计表结构
# 创建用户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL,
UNIQUE (tenant_id, username)
);”
# 创建订单表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id, user_id) REFERENCES fgedu_user (tenant_id, id)
);”
# 创建索引
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_user_tenant_id ON fgedu_user (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_order_tenant_id ON fgedu_order (tenant_id);”
## 2. 插入测试数据
# 插入租户1的数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_user (tenant_id, username, email, password, create_time) VALUES
(1, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now()),
(1, ‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant1.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order (tenant_id, user_id, order_date, total_amount, status, create_time) VALUES
(1, 1, ‘2024-01-01’, 100.00, ‘completed’, now()),
(1, 2, ‘2024-01-02’, 200.00, ‘pending’, now());”
# 插入租户2的数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_user (tenant_id, username, email, password, create_time) VALUES
(2, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password1’, now()),
(2, ‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant2.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order (tenant_id, user_id, order_date, total_amount, status, create_time) VALUES
(2, 3, ‘2024-01-01’, 150.00, ‘completed’, now()),
(2, 4, ‘2024-01-02’, 250.00, ‘pending’, now());”
## 3. 验证数据隔离
# 查询租户1的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 1;”
# 查询租户2的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 2;”
# 验证跨租户数据隔离
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 1 AND username = ‘fgedu_user1’;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 2 AND username = ‘fgedu_user1’;”
3.1.2 共享数据库独立表方案实施
# 共享数据库独立表方案实施步骤
## 1. 创建租户表
# 创建租户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,学习交流加群风哥微信: itpux-com
create_time TIMESTAMP NOT NULL
);”
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, create_time) VALUES
(‘tenant1’, now()),
(‘tenant2’, now());”
## 2. 创建租户表结构
# 为租户1创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant1_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant1_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES tenant1_user (id)
);”
# 为租户2创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant2_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant2_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES tenant2_user (id)
);”
## 3. 插入测试数据
# 插入租户1的数据
$ ksql -U system -d fgedudb -c “INSERT INTO tenant1_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant1.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO tenant1_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 100.00, ‘completed’, now()),
(2, ‘2024-01-02’, 200.00, ‘pending’, now());”
# 插入租户2的数据
$ ksql -U system -d fgedudb -c “INSERT INTO tenant2_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant2.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO tenant2_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 150.00, ‘completed’, now()),
(2, ‘2024-01-02’, 250.00, ‘pending’, now());”
## 4. 验证数据隔离
# 查询租户1的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant1_user;”
# 查询租户2的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant2_user;”
# 验证跨租户数据隔离
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant1_user WHERE username = ‘fgedu_user1’;”
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant2_user WHERE username = ‘fgedu_user1’;”
## 1. 创建租户表
# 创建租户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,学习交流加群风哥微信: itpux-com
create_time TIMESTAMP NOT NULL
);”
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, create_time) VALUES
(‘tenant1’, now()),
(‘tenant2’, now());”
## 2. 创建租户表结构
# 为租户1创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant1_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant1_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES tenant1_user (id)
);”
# 为租户2创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant2_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE tenant2_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES tenant2_user (id)
);”
## 3. 插入测试数据
# 插入租户1的数据
$ ksql -U system -d fgedudb -c “INSERT INTO tenant1_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant1.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO tenant1_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 100.00, ‘completed’, now()),
(2, ‘2024-01-02’, 200.00, ‘pending’, now());”
# 插入租户2的数据
$ ksql -U system -d fgedudb -c “INSERT INTO tenant2_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant2.com’, ‘password2’, now());”
$ ksql -U system -d fgedudb -c “INSERT INTO tenant2_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 150.00, ‘completed’, now()),
(2, ‘2024-01-02’, 250.00, ‘pending’, now());”
## 4. 验证数据隔离
# 查询租户1的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant1_user;”
# 查询租户2的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant2_user;”
# 验证跨租户数据隔离
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant1_user WHERE username = ‘fgedu_user1’;”
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant2_user WHERE username = ‘fgedu_user1’;”
3.1.3 独立数据库方案实施
# 独立数据库方案实施步骤
## 1. 创建租户数据库
# 创建租户1数据库
$ createdb -h fgedu.localhost -p 54321 tenant1_db
# 创建租户2数据库
$ createdb -h fgedu.localhost -p 54321 tenant2_db
## 2. 创建用户和权限
# 创建租户1用户
$ ksql -U system -d postgres -c “CREATE USER tenant1_user WITH PASSWORD ‘tenant1_pass’;”
$ ksql -U system -d postgres -c “GRANT ALL PRIVILEGES ON DATABASE tenant1_db TO tenant1_user;”
# 创建租户2用户
$ ksql -U system -d postgres -c “CREATE USER tenant2_user WITH PASSWORD ‘tenant2_pass’;”
$ ksql -U system -d postgres -c “GRANT ALL PRIVILEGES ON DATABASE tenant2_db TO tenant2_user;”
## 3. 创建表结构
# 在租户1数据库创建表
$ ksql -U tenant1_user -d tenant1_db -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U tenant1_user -d tenant1_db -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES fgedu_user (id)
);”
# 在租户2数据库创建表
$ ksql -U tenant2_user -d tenant2_db -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U tenant2_user -d tenant2_db -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES fgedu_user (id)
);”
## 4. 插入测试数据
# 插入租户1的数据
$ ksql -U tenant1_user -d tenant1_db -c “INSERT INTO fgedu_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant1.com’, ‘password2’, now());”
$ ksql -U tenant1_user -d tenant1_db -c “INSERT INTO fgedu_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 100.00, ‘completed’, now()),
(2, ‘2024-01-02’, 200.00, ‘pending’, now());”
# 插入租户2的数据
$ ksql -U tenant2_user -d tenant2_db -c “INSERT INTO fgedu_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant2.com’, ‘password2’, now());”
$ ksql -U tenant2_user -d tenant2_db -c “INSERT INTO fgedu_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 150.00, ‘completed’, now()),
(2, ‘2024-01-02’, 250.00, ‘pending’, now());”
## 5. 验证数据隔离
# 查询租户1的数据
$ ksql -U tenant1_user -d tenant1_db -c “SELECT * FROM fgedu_user;”
# 查询租户2的数据
$ ksql -U tenant2_user -d tenant2_db -c “SELECT * FROM fgedu_user;”
# 验证跨租户数据隔离
$ ksql -U tenant1_user -d tenant2_db -c “SELECT * FROM fgedu_user;” # 应该失败
## 1. 创建租户数据库
# 创建租户1数据库
$ createdb -h fgedu.localhost -p 54321 tenant1_db
# 创建租户2数据库
$ createdb -h fgedu.localhost -p 54321 tenant2_db
## 2. 创建用户和权限
# 创建租户1用户
$ ksql -U system -d postgres -c “CREATE USER tenant1_user WITH PASSWORD ‘tenant1_pass’;”
$ ksql -U system -d postgres -c “GRANT ALL PRIVILEGES ON DATABASE tenant1_db TO tenant1_user;”
# 创建租户2用户
$ ksql -U system -d postgres -c “CREATE USER tenant2_user WITH PASSWORD ‘tenant2_pass’;”
$ ksql -U system -d postgres -c “GRANT ALL PRIVILEGES ON DATABASE tenant2_db TO tenant2_user;”
## 3. 创建表结构
# 在租户1数据库创建表
$ ksql -U tenant1_user -d tenant1_db -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U tenant1_user -d tenant1_db -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES fgedu_user (id)
);”
# 在租户2数据库创建表
$ ksql -U tenant2_user -d tenant2_db -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL
);”
$ ksql -U tenant2_user -d tenant2_db -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (user_id) REFERENCES fgedu_user (id)
);”
## 4. 插入测试数据
# 插入租户1的数据
$ ksql -U tenant1_user -d tenant1_db -c “INSERT INTO fgedu_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant1.com’, ‘password2’, now());”
$ ksql -U tenant1_user -d tenant1_db -c “INSERT INTO fgedu_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 100.00, ‘completed’, now()),
(2, ‘2024-01-02’, 200.00, ‘pending’, now());”
# 插入租户2的数据
$ ksql -U tenant2_user -d tenant2_db -c “INSERT INTO fgedu_user (username, email, password, create_time) VALUES
(‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password1’, now()),
(‘fgedu_user2’, ‘fgedu_user2@fgedu_tenant2.com’, ‘password2’, now());”
$ ksql -U tenant2_user -d tenant2_db -c “INSERT INTO fgedu_order (user_id, order_date, total_amount, status, create_time) VALUES
(1, ‘2024-01-01’, 150.00, ‘completed’, now()),
(2, ‘2024-01-02’, 250.00, ‘pending’, now());”
## 5. 验证数据隔离
# 查询租户1的数据
$ ksql -U tenant1_user -d tenant1_db -c “SELECT * FROM fgedu_user;”
# 查询租户2的数据
$ ksql -U tenant2_user -d tenant2_db -c “SELECT * FROM fgedu_user;”
# 验证跨租户数据隔离
$ ksql -U tenant1_user -d tenant2_db -c “SELECT * FROM fgedu_user;” # 应该失败
3.2 多租户管理与监控
3.2.1 多租户管理
# 多租户管理
## 1. 租户管理
# 创建租户管理表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, status, create_time, update_time) VALUES
(‘tenant1’, ‘active’, now(), now()),
(‘tenant2’, ‘active’, now(), now());”
## 2. 租户配置管理
# 创建租户配置表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant_config (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
config_key VARCHAR(100) NOT NULL,
config_value VARCHAR(255) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 插入配置数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant_config (tenant_id, config_key, config_value, create_time, update_time) VALUES
(1, ‘max_users’, ‘100’, now(), now()),
(1, ‘max_orders’, ‘1000’, now(), now()),
(2, ‘max_users’, ‘200’, now(), now()),
(2, ‘max_orders’, ‘2000’, now(), now());”
## 3. 租户资源管理
# 创建租户资源表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant_resource (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
resource_type VARCHAR(100) NOT NULL,
used_amount INTEGER NOT NULL,
total_amount INTEGER NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 插入资源数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant_resource (tenant_id, resource_type, used_amount, total_amount, update_time) VALUES
(1, ‘storage’, 1024, 10240, now()),
(1, ‘cpu’, 2, 4, now()),
(2, ‘storage’, 2048, 20480, now()),
(2, ‘cpu’, 4, 8, now());”
## 1. 租户管理
# 创建租户管理表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, status, create_time, update_time) VALUES
(‘tenant1’, ‘active’, now(), now()),
(‘tenant2’, ‘active’, now(), now());”
## 2. 租户配置管理
# 创建租户配置表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant_config (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
config_key VARCHAR(100) NOT NULL,
config_value VARCHAR(255) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 插入配置数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant_config (tenant_id, config_key, config_value, create_time, update_time) VALUES
(1, ‘max_users’, ‘100’, now(), now()),
(1, ‘max_orders’, ‘1000’, now(), now()),
(2, ‘max_users’, ‘200’, now(), now()),
(2, ‘max_orders’, ‘2000’, now(), now());”
## 3. 租户资源管理
# 创建租户资源表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant_resource (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
resource_type VARCHAR(100) NOT NULL,
used_amount INTEGER NOT NULL,
total_amount INTEGER NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 插入资源数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant_resource (tenant_id, resource_type, used_amount, total_amount, update_time) VALUES
(1, ‘storage’, 1024, 10240, now()),
(1, ‘cpu’, 2, 4, now()),
(2, ‘storage’, 2048, 20480, now()),
(2, ‘cpu’, 4, 8, now());”
3.2.2 多租户监控
# 多租户监控
## 1. 监控指标
# 创建监控表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant_monitor (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
metric_name VARCHAR(100) NOT NULL,
metric_value DECIMAL(10,2) NOT NULL,
collection_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
## 2. 监控脚本
# 创建监控脚本
$ vi /kingbase/scripts/tenant_monitor.sh
#!/bin/bash
# tenant_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 租户列表
TENANTS=(1 2)
# 监控时间
COLLECTION_TIME=$(date +”%Y-%m-%d %H:%M:%S”)
# 监控每个租户
for TENANT_ID in “${TENANTS[@]}”; do
# 监控存储使用情况
STORAGE_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘storage'” | grep -v used_amount)
# 监控CPU使用情况
CPU_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘cpu'” | grep -v used_amount)
# 监控用户数量
USER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_user WHERE tenant_id = $TENANT_ID” | grep -v count)
# 监控订单数量
ORDER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_order WHERE tenant_id = $TENANT_ID” | grep -v count)
# 插入监控数据
ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant_monitor (tenant_id, metric_name, metric_value, collection_time) VALUES
($TENANT_ID, ‘storage_usage’, $STORAGE_USAGE, ‘$COLLECTION_TIME’),
($TENANT_ID, ‘cpu_usage’, $CPU_USAGE, ‘$COLLECTION_TIME’),
($TENANT_ID, ‘user_count’, $USER_COUNT, ‘$COLLECTION_TIME’),
($TENANT_ID, ‘order_count’, $ORDER_COUNT, ‘$COLLECTION_TIME’);”
done
# 设置执行权限
$ chmod +x /kingbase/scripts/tenant_monitor.sh
# 配置crontab
$ crontab -e
*/5 * * * * /kingbase/scripts/tenant_monitor.sh
## 3. 监控告警
# 创建告警脚本
$ vi /kingbase/scripts/tenant_alert.sh
#!/bin/bash
# tenant_alert.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 租户列表
TENANTS=(1 2)
# 检查每个租户
for TENANT_ID in “${TENANTS[@]}”; do
# 检查存储使用情况
STORAGE_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount * 100.0 / total_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘storage'” | grep -v ?column?)
# 检查CPU使用情况
CPU_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount * 100.0 / total_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘cpu'” | grep -v ?column?)
# 检查用户数量
USER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_user WHERE tenant_id = $TENANT_ID” | grep -v count)
MAX_USERS=$(ksql -U system -d fgedudb -c “SELECT config_value FROM fgedu_tenant_config WHERE tenant_id = $TENANT_ID AND config_key = ‘max_users'” | grep -v config_value)
# 检查订单数量
ORDER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_order WHERE tenant_id = $TENANT_ID” | grep -v count)
MAX_ORDERS=$(ksql -U system -d fgedudb -c “SELECT config_value FROM fgedu_tenant_config WHERE tenant_id = $TENANT_ID AND config_key = ‘max_orders'” | grep -v config_value)
# 生成告警
if (( $(echo “$STORAGE_USAGE > 80” | bc -l) )); then
echo “告警:租户 $TENANT_ID 存储使用率超过80%,当前使用率:$STORAGE_USAGE%” | mail -s “租户存储告警” admin@fgedu.net.cn
fi
if (( $(echo “$CPU_USAGE > 80” | bc -l) )); then
echo “告警:租户 $TENANT_ID CPU使用率超过80%,当前使用率:$CPU_USAGE%” | mail -s “租户CPU告警” admin@fgedu.net.cn
fi
if (( $USER_COUNT > $MAX_USERS )); then
echo “告警:租户 $TENANT_ID 用户数量超过上限,当前数量:$USER_COUNT,上限:$MAX_USERS” | mail -s “租户用户数量告警” admin@fgedu.net.cn
fi
if (( $ORDER_COUNT > $MAX_ORDERS )); then
echo “告警:租户 $TENANT_ID 订单数量超过上限,当前数量:$ORDER_COUNT,上限:$MAX_ORDERS” | mail -s “租户订单数量告警” admin@fgedu.net.cn
fi
done
# 设置执行权限
$ chmod +x /kingbase/scripts/tenant_alert.sh
# 配置crontab
$ crontab -e
*/10 * * * * /kingbase/scripts/tenant_alert.sh
## 1. 监控指标
# 创建监控表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant_monitor (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
metric_name VARCHAR(100) NOT NULL,
metric_value DECIMAL(10,2) NOT NULL,
collection_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
## 2. 监控脚本
# 创建监控脚本
$ vi /kingbase/scripts/tenant_monitor.sh
#!/bin/bash
# tenant_monitor.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 租户列表
TENANTS=(1 2)
# 监控时间
COLLECTION_TIME=$(date +”%Y-%m-%d %H:%M:%S”)
# 监控每个租户
for TENANT_ID in “${TENANTS[@]}”; do
# 监控存储使用情况
STORAGE_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘storage'” | grep -v used_amount)
# 监控CPU使用情况
CPU_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘cpu'” | grep -v used_amount)
# 监控用户数量
USER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_user WHERE tenant_id = $TENANT_ID” | grep -v count)
# 监控订单数量
ORDER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_order WHERE tenant_id = $TENANT_ID” | grep -v count)
# 插入监控数据
ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant_monitor (tenant_id, metric_name, metric_value, collection_time) VALUES
($TENANT_ID, ‘storage_usage’, $STORAGE_USAGE, ‘$COLLECTION_TIME’),
($TENANT_ID, ‘cpu_usage’, $CPU_USAGE, ‘$COLLECTION_TIME’),
($TENANT_ID, ‘user_count’, $USER_COUNT, ‘$COLLECTION_TIME’),
($TENANT_ID, ‘order_count’, $ORDER_COUNT, ‘$COLLECTION_TIME’);”
done
# 设置执行权限
$ chmod +x /kingbase/scripts/tenant_monitor.sh
# 配置crontab
$ crontab -e
*/5 * * * * /kingbase/scripts/tenant_monitor.sh
## 3. 监控告警
# 创建告警脚本
$ vi /kingbase/scripts/tenant_alert.sh
#!/bin/bash
# tenant_alert.sh
# from:www.itpux.com.qq113257174.wx:itpux-com
# web: `http://www.fgedu.net.cn`
# 租户列表
TENANTS=(1 2)
# 检查每个租户
for TENANT_ID in “${TENANTS[@]}”; do
# 检查存储使用情况
STORAGE_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount * 100.0 / total_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘storage'” | grep -v ?column?)
# 检查CPU使用情况
CPU_USAGE=$(ksql -U system -d fgedudb -c “SELECT used_amount * 100.0 / total_amount FROM fgedu_tenant_resource WHERE tenant_id = $TENANT_ID AND resource_type = ‘cpu'” | grep -v ?column?)
# 检查用户数量
USER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_user WHERE tenant_id = $TENANT_ID” | grep -v count)
MAX_USERS=$(ksql -U system -d fgedudb -c “SELECT config_value FROM fgedu_tenant_config WHERE tenant_id = $TENANT_ID AND config_key = ‘max_users'” | grep -v config_value)
# 检查订单数量
ORDER_COUNT=$(ksql -U system -d fgedudb -c “SELECT COUNT(*) FROM fgedu_order WHERE tenant_id = $TENANT_ID” | grep -v count)
MAX_ORDERS=$(ksql -U system -d fgedudb -c “SELECT config_value FROM fgedu_tenant_config WHERE tenant_id = $TENANT_ID AND config_key = ‘max_orders'” | grep -v config_value)
# 生成告警
if (( $(echo “$STORAGE_USAGE > 80” | bc -l) )); then
echo “告警:租户 $TENANT_ID 存储使用率超过80%,当前使用率:$STORAGE_USAGE%” | mail -s “租户存储告警” admin@fgedu.net.cn
fi
if (( $(echo “$CPU_USAGE > 80” | bc -l) )); then
echo “告警:租户 $TENANT_ID CPU使用率超过80%,当前使用率:$CPU_USAGE%” | mail -s “租户CPU告警” admin@fgedu.net.cn
fi
if (( $USER_COUNT > $MAX_USERS )); then
echo “告警:租户 $TENANT_ID 用户数量超过上限,当前数量:$USER_COUNT,上限:$MAX_USERS” | mail -s “租户用户数量告警” admin@fgedu.net.cn
fi
if (( $ORDER_COUNT > $MAX_ORDERS )); then
echo “告警:租户 $TENANT_ID 订单数量超过上限,当前数量:$ORDER_COUNT,上限:$MAX_ORDERS” | mail -s “租户订单数量告警” admin@fgedu.net.cn
fi
done
# 设置执行权限
$ chmod +x /kingbase/scripts/tenant_alert.sh
# 配置crontab
$ crontab -e
*/10 * * * * /kingbase/scripts/tenant_alert.sh
3.3 多租户迁移与升级
3.3.1 多租户迁移
# 多租户迁移
## 1. 租户数据导出
# 导出租户1的数据
$ pg_dump -h fgedu.localhost -p 54321 -U system -d fgedudb -t fgedu_user -t fgedu_order -c > tenant1_dump.sql
# 过滤出租户1的数据
$ grep -E “INSERT INTO fgedu_user.*tenant_id = 1” tenant1_dump.sql > tenant1_user.sql
$ grep -E “INSERT INTO fgedu_order.*tenant_id = 1” tenant1_dump.sql > tenant1_order.sql
## 2. 租户数据导入
# 创建新租户数据库
$ createdb -h fgedu.localhost -p 54321 tenant3_db
# 创建用户和权限
$ ksql -U system -d postgres -c “CREATE USER tenant3_user WITH PASSWORD ‘tenant3_pass’;”
$ ksql -U system -d postgres -c “GRANT ALL PRIVILEGES ON DATABASE tenant3_db TO tenant3_user;”
# 创建表结构
$ ksql -U tenant3_user -d tenant3_db -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL,
UNIQUE (tenant_id, username)
);”
$ ksql -U tenant3_user -d tenant3_db -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id, user_id) REFERENCES fgedu_user (tenant_id, id)
);”
# 导入数据
$ ksql -U tenant3_user -d tenant3_db -c “BEGIN;”
$ ksql -U tenant3_user -d tenant3_db -f tenant1_user.sql
$ ksql -U tenant3_user -d tenant3_db -f tenant1_order.sql
$ ksql -U tenant3_user -d tenant3_db -c “COMMIT;”
## 3. 验证迁移
# 验证数据
$ ksql -U tenant3_user -d tenant3_db -c “SELECT COUNT(*) FROM fgedu_user;”
$ ksql -U tenant3_user -d tenant3_db -c “SELECT COUNT(*) FROM fgedu_order;”
## 1. 租户数据导出
# 导出租户1的数据
$ pg_dump -h fgedu.localhost -p 54321 -U system -d fgedudb -t fgedu_user -t fgedu_order -c > tenant1_dump.sql
# 过滤出租户1的数据
$ grep -E “INSERT INTO fgedu_user.*tenant_id = 1” tenant1_dump.sql > tenant1_user.sql
$ grep -E “INSERT INTO fgedu_order.*tenant_id = 1” tenant1_dump.sql > tenant1_order.sql
## 2. 租户数据导入
# 创建新租户数据库
$ createdb -h fgedu.localhost -p 54321 tenant3_db
# 创建用户和权限
$ ksql -U system -d postgres -c “CREATE USER tenant3_user WITH PASSWORD ‘tenant3_pass’;”
$ ksql -U system -d postgres -c “GRANT ALL PRIVILEGES ON DATABASE tenant3_db TO tenant3_user;”
# 创建表结构
$ ksql -U tenant3_user -d tenant3_db -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL,
UNIQUE (tenant_id, username)
);”
$ ksql -U tenant3_user -d tenant3_db -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id, user_id) REFERENCES fgedu_user (tenant_id, id)
);”
# 导入数据
$ ksql -U tenant3_user -d tenant3_db -c “BEGIN;”
$ ksql -U tenant3_user -d tenant3_db -f tenant1_user.sql
$ ksql -U tenant3_user -d tenant3_db -f tenant1_order.sql
$ ksql -U tenant3_user -d tenant3_db -c “COMMIT;”
## 3. 验证迁移
# 验证数据
$ ksql -U tenant3_user -d tenant3_db -c “SELECT COUNT(*) FROM fgedu_user;”
$ ksql -U tenant3_user -d tenant3_db -c “SELECT COUNT(*) FROM fgedu_order;”
3.3.2 多租户升级
# 多租户升级
## 1. 表结构升级
# 为所有租户添加新字段
$ ksql -U system -d fgedudb -c “ALTER TABLE fgedu_user ADD COLUMN phone VARCHAR(20);”
# 为共享数据库独立表方案的租户表添加新字段
$ ksql -U system -d fgedudb -c “ALTER TABLE tenant1_user ADD COLUMN phone VARCHAR(20);”
$ ksql -U system -d fgedudb -c “ALTER TABLE tenant2_user ADD COLUMN phone VARCHAR(20);”
# 为独立数据库方案的租户数据库添加新字段
$ ksql -U tenant1_user -d tenant1_db -c “ALTER TABLE fgedu_user ADD COLUMN phone VARCHAR(20);”
$ ksql -U tenant2_user -d tenant2_db -c “ALTER TABLE fgedu_user ADD COLUMN phone VARCHAR(20);”
## 2. 数据升级
# 更新所有租户的新字段
$ ksql -U system -d fgedudb -c “UPDATE fgedu_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
# 更新共享数据库独立表方案的租户表
$ ksql -U system -d fgedudb -c “UPDATE tenant1_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
$ ksql -U system -d fgedudb -c “UPDATE tenant2_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
# 更新独立数据库方案的租户数据库
$ ksql -U tenant1_user -d tenant1_db -c “UPDATE fgedu_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
$ ksql -U tenant2_user -d tenant2_db -c “UPDATE fgedu_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
## 3. 验证升级
# 验证共享数据库共享表方案
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user LIMIT 5;”
# 验证共享数据库独立表方案
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant1_user LIMIT 5;”
# 验证独立数据库方案
$ ksql -U tenant1_user -d tenant1_db -c “SELECT * FROM fgedu_user LIMIT 5;”
## 1. 表结构升级
# 为所有租户添加新字段
$ ksql -U system -d fgedudb -c “ALTER TABLE fgedu_user ADD COLUMN phone VARCHAR(20);”
# 为共享数据库独立表方案的租户表添加新字段
$ ksql -U system -d fgedudb -c “ALTER TABLE tenant1_user ADD COLUMN phone VARCHAR(20);”
$ ksql -U system -d fgedudb -c “ALTER TABLE tenant2_user ADD COLUMN phone VARCHAR(20);”
# 为独立数据库方案的租户数据库添加新字段
$ ksql -U tenant1_user -d tenant1_db -c “ALTER TABLE fgedu_user ADD COLUMN phone VARCHAR(20);”
$ ksql -U tenant2_user -d tenant2_db -c “ALTER TABLE fgedu_user ADD COLUMN phone VARCHAR(20);”
## 2. 数据升级
# 更新所有租户的新字段
$ ksql -U system -d fgedudb -c “UPDATE fgedu_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
# 更新共享数据库独立表方案的租户表
$ ksql -U system -d fgedudb -c “UPDATE tenant1_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
$ ksql -U system -d fgedudb -c “UPDATE tenant2_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
# 更新独立数据库方案的租户数据库
$ ksql -U tenant1_user -d tenant1_db -c “UPDATE fgedu_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
$ ksql -U tenant2_user -d tenant2_db -c “UPDATE fgedu_user SET phone = ‘13800138000’ WHERE phone IS NULL;”
## 3. 验证升级
# 验证共享数据库共享表方案
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user LIMIT 5;”
# 验证共享数据库独立表方案
$ ksql -U system -d fgedudb -c “SELECT * FROM tenant1_user LIMIT 5;”
# 验证独立数据库方案
$ ksql -U tenant1_user -d tenant1_db -c “SELECT * FROM fgedu_user LIMIT 5;”
Part04-生产案例与实战讲解
4.1 共享数据库共享表方案
4.1.1 案例背景
某SaaS应用需要支持多个租户,每个租户的数据量较小,对隔离性要求不高,需要使用共享数据库共享表方案。
4.1.2 解决方案
共享数据库共享表方案实施:
- 设计表结构:在每个表中添加租户ID字段
- 创建索引:在租户ID字段上创建索引
- 数据访问控制:在应用层添加租户ID过滤条件
- 监控与管理:实施租户监控和管理
# 实施步骤
## 1. 设计表结构
# 创建租户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
subdomain VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
# 创建用户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
UNIQUE (tenant_id, username),
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 创建产品表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_product (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) NOT NULL,
description TEXT,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 创建订单表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,更多学习教程公众号风哥教程itpux_com
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id),
FOREIGN KEY (tenant_id, user_id) REFERENCES fgedu_user (tenant_id, id)
);”
# 创建订单明细表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_order_item (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
order_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
quantity INTEGER NOT NULL,
price DECIMAL(10,2) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id),
FOREIGN KEY (tenant_id, order_id) REFERENCES fgedu_order (tenant_id, id),
FOREIGN KEY (tenant_id, product_id) REFERENCES fgedu_product (tenant_id, id)
);”
## 2. 创建索引
# 创建索引
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_user_tenant_id ON fgedu_user (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_product_tenant_id ON fgedu_product (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_order_tenant_id ON fgedu_order (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_order_item_tenant_id ON fgedu_order_item (tenant_id);”
## 3. 插入测试数据
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, subdomain, status, create_time, update_time) VALUES
(‘租户1’, ‘tenant1’, ‘active’, now(), now()),
(‘租户2’, ‘tenant2’, ‘active’, now(), now());”
# 插入用户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_user (tenant_id, username, email, password, create_time, update_time) VALUES
(1, ‘admin’, ‘admin@fgedu_tenant1.com’, ‘password1’, now(), now()),
(1, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now(), now()),
(2, ‘admin’, ‘admin@fgedu_tenant2.com’, ‘password2’, now(), now()),
(2, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password2’, now(), now());”
# 插入产品数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_product (tenant_id, name, price, description, create_time, update_time) VALUES
(1, ‘产品1’, 100.00, ‘产品1描述’, now(), now()),
(1, ‘产品2’, 200.00, ‘产品2描述’, now(), now()),
(2, ‘产品A’, 150.00, ‘产品A描述’, now(), now()),
(2, ‘产品B’, 250.00, ‘产品B描述’, now(), now());”
# 插入订单数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order (tenant_id, user_id, order_date, total_amount, status, create_time, update_time) VALUES
(1, 1, ‘2024-01-01’, 300.00, ‘completed’, now(), now()),
(2, 3, ‘2024-01-01’, 400.00, ‘pending’, now(), now());”
# 插入订单明细数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order_item (tenant_id, order_id, product_id, quantity, price, create_time) VALUES
(1, 1, 1, 1, 100.00, now()),
(1, 1, 2, 1, 200.00, now()),
(2, 2, 3, 1, 150.00, now()),
(2, 2, 4, 1, 250.00, now());”
## 4. 验证数据隔离
# 查询租户1的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 1;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_product WHERE tenant_id = 1;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_order WHERE tenant_id = 1;”
# 查询租户2的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 2;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_product WHERE tenant_id = 2;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_order WHERE tenant_id = 2;”
## 5. 应用程序适配
# 修改应用程序,添加租户ID过滤
# 在每个查询中添加WHERE tenant_id = ? 条件
# 在每个插入操作中添加tenant_id字段
## 1. 设计表结构
# 创建租户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
subdomain VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
# 创建用户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_user (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
username VARCHAR(100) NOT NULL,
email VARCHAR(100) NOT NULL,
password VARCHAR(100) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
UNIQUE (tenant_id, username),
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 创建产品表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_product (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
name VARCHAR(100) NOT NULL,
price DECIMAL(10,2) NOT NULL,
description TEXT,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id)
);”
# 创建订单表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_order (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
user_id INTEGER NOT NULL,
order_date DATE NOT NULL,
total_amount DECIMAL(10,2) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,更多学习教程公众号风哥教程itpux_com
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id),
FOREIGN KEY (tenant_id, user_id) REFERENCES fgedu_user (tenant_id, id)
);”
# 创建订单明细表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_order_item (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
order_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
quantity INTEGER NOT NULL,
price DECIMAL(10,2) NOT NULL,
create_time TIMESTAMP NOT NULL,
FOREIGN KEY (tenant_id) REFERENCES fgedu_tenant (id),
FOREIGN KEY (tenant_id, order_id) REFERENCES fgedu_order (tenant_id, id),
FOREIGN KEY (tenant_id, product_id) REFERENCES fgedu_product (tenant_id, id)
);”
## 2. 创建索引
# 创建索引
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_user_tenant_id ON fgedu_user (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_product_tenant_id ON fgedu_product (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_order_tenant_id ON fgedu_order (tenant_id);”
$ ksql -U system -d fgedudb -c “CREATE INDEX idx_fgedu_order_item_tenant_id ON fgedu_order_item (tenant_id);”
## 3. 插入测试数据
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, subdomain, status, create_time, update_time) VALUES
(‘租户1’, ‘tenant1’, ‘active’, now(), now()),
(‘租户2’, ‘tenant2’, ‘active’, now(), now());”
# 插入用户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_user (tenant_id, username, email, password, create_time, update_time) VALUES
(1, ‘admin’, ‘admin@fgedu_tenant1.com’, ‘password1’, now(), now()),
(1, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant1.com’, ‘password1’, now(), now()),
(2, ‘admin’, ‘admin@fgedu_tenant2.com’, ‘password2’, now(), now()),
(2, ‘fgedu_user1’, ‘fgedu_user1@fgedu_tenant2.com’, ‘password2’, now(), now());”
# 插入产品数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_product (tenant_id, name, price, description, create_time, update_time) VALUES
(1, ‘产品1’, 100.00, ‘产品1描述’, now(), now()),
(1, ‘产品2’, 200.00, ‘产品2描述’, now(), now()),
(2, ‘产品A’, 150.00, ‘产品A描述’, now(), now()),
(2, ‘产品B’, 250.00, ‘产品B描述’, now(), now());”
# 插入订单数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order (tenant_id, user_id, order_date, total_amount, status, create_time, update_time) VALUES
(1, 1, ‘2024-01-01’, 300.00, ‘completed’, now(), now()),
(2, 3, ‘2024-01-01’, 400.00, ‘pending’, now(), now());”
# 插入订单明细数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_order_item (tenant_id, order_id, product_id, quantity, price, create_time) VALUES
(1, 1, 1, 1, 100.00, now()),
(1, 1, 2, 1, 200.00, now()),
(2, 2, 3, 1, 150.00, now()),
(2, 2, 4, 1, 250.00, now());”
## 4. 验证数据隔离
# 查询租户1的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 1;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_product WHERE tenant_id = 1;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_order WHERE tenant_id = 1;”
# 查询租户2的数据
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_user WHERE tenant_id = 2;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_product WHERE tenant_id = 2;”
$ ksql -U system -d fgedudb -c “SELECT * FROM fgedu_order WHERE tenant_id = 2;”
## 5. 应用程序适配
# 修改应用程序,添加租户ID过滤
# 在每个查询中添加WHERE tenant_id = ? 条件
# 在每个插入操作中添加tenant_id字段
4.1.3 实施效果
- 资源利用率:多个租户共享同一套数据库资源,提高资源利用率
- 管理简单:集中管理所有租户的数据,简化运维管理
- 成本降低:减少硬件和软件的投入,降低运维成本
- 性能满足:对于数据量较小的租户,性能满足需求
- 扩展性:可以通过添加节点来扩展系统容量
4.2 共享数据库独立表方案
4.2.1 案例背景
某企业内部系统需要支持多个部门作为租户,每个部门的数据量较大,对隔离性有一定要求,需要使用共享数据库独立表方案。
4.2.2 解决方案
共享数据库独立表方案实施:
- 设计表命名规则:表名格式为{租户ID}_{表名}
- 创建租户表结构:为每个租户创建独立的表,更多视频教程www.fgedu.net.cn
- 数据访问控制:在应用层根据租户ID选择对应的表
- 管理与监控:实施租户管理和监控
# 实施步骤
## 1. 设计表结构
# 创建租户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, status, create_time, update_time) VALUES
(‘财务部’, ‘active’, now(), now()),
(‘市场部’, ‘active’, now(), now()),
(‘研发部’, ‘active’, now(), now());”
## 2. 创建租户表结构
# 为财务部创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE dept1_employee (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
position VARCHAR(100) NOT NULL,
salary DECIMAL(10,2) NOT NULL,
hire_date DATE NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE dept1_expense (
id SERIAL PRIMARY KEY,
employee_id INTEGER NOT NULL,
amount DECIMAL(10,2) NOT NULL,
expense_date DATE NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (employee_id) REFERENCES dept1_employee (id)
);”
# 为市场部创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE dept2_employee (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
position VARCHAR(100) NOT NULL,
salary DECIMAL(10,2) NOT NULL,
hire_date DATE NOT NULL,
create_time TIMESTAMP NOT NULL,from DB视频:www.itpux.com
update_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE dept2_expense (
id SERIAL PRIMARY KEY,
employee_id INTEGER NOT NULL,
amount DECIMAL(10,2) NOT NULL,
expense_date DATE NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (employee_id) REFERENCES dept2_emplo
## 1. 设计表结构
# 创建租户表
$ ksql -U system -d fgedudb -c “CREATE TABLE fgedu_tenant (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
# 插入租户数据
$ ksql -U system -d fgedudb -c “INSERT INTO fgedu_tenant (name, status, create_time, update_time) VALUES
(‘财务部’, ‘active’, now(), now()),
(‘市场部’, ‘active’, now(), now()),
(‘研发部’, ‘active’, now(), now());”
## 2. 创建租户表结构
# 为财务部创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE dept1_employee (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
position VARCHAR(100) NOT NULL,
salary DECIMAL(10,2) NOT NULL,
hire_date DATE NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE dept1_expense (
id SERIAL PRIMARY KEY,
employee_id INTEGER NOT NULL,
amount DECIMAL(10,2) NOT NULL,
expense_date DATE NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (employee_id) REFERENCES dept1_employee (id)
);”
# 为市场部创建表
$ ksql -U system -d fgedudb -c “CREATE TABLE dept2_employee (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
position VARCHAR(100) NOT NULL,
salary DECIMAL(10,2) NOT NULL,
hire_date DATE NOT NULL,
create_time TIMESTAMP NOT NULL,from DB视频:www.itpux.com
update_time TIMESTAMP NOT NULL
);”
$ ksql -U system -d fgedudb -c “CREATE TABLE dept2_expense (
id SERIAL PRIMARY KEY,
employee_id INTEGER NOT NULL,
amount DECIMAL(10,2) NOT NULL,
expense_date DATE NOT NULL,
description TEXT,
status VARCHAR(20) NOT NULL,
create_time TIMESTAMP NOT NULL,
update_time TIMESTAMP NOT NULL,
FOREIGN KEY (employee_id) REFERENCES dept2_emplo
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
