在多租户架构的业务系统中,资源统计往往需要同时区分不同租户的数据,避免租户之间的数据混淆,同时还需要按照业务维度进行分组展示统计结果。要实现带租户标识维度的分组资源统计,首先需要设计合理的表结构,确保每条业务数据都关联对应的租户标识。

基础表结构设计
多租户场景下的业务表通常需要包含租户标识字段,以资源使用记录表为例,基础结构如下:
-- 创建资源使用记录表,包含租户标识字段
CREATE TABLE resource_usage (
id INT PRIMARY KEY AUTO_INCREMENT,
tenant_id VARCHAR(32) NOT NULL COMMENT '租户标识',
resource_type VARCHAR(20) NOT NULL COMMENT '资源类型',
usage_amount DECIMAL(10,2) NOT NULL COMMENT '资源使用量',
usage_date DATE NOT NULL COMMENT '使用日期',
INDEX idx_tenant_date (tenant_id, usage_date)
);
普通分组资源统计实现
如果不考虑租户维度,仅按照资源类型分组统计总使用量,SQL实现如下:
-- 按资源类型分组统计总使用量
SELECT
resource_type,
SUM(usage_amount) AS total_usage
FROM resource_usage
GROUP BY resource_type;
增加租户标识维度的分组统计
需要同时按照租户标识和资源类型进行分组,统计每个租户下不同资源类型的使用总量,SQL实现如下:
-- 增加租户标识维度,按租户和资源类型分组统计
SELECT
tenant_id,
resource_type,
SUM(usage_amount) AS total_usage
FROM resource_usage
GROUP BY tenant_id, resource_type
ORDER BY tenant_id, resource_type;
带时间范围的多维度统计
如果需要统计指定时间范围内,每个租户按资源类型的月度使用量,可以结合时间条件进行查询:
-- 统计2024年1月每个租户各资源类型的月度使用量
SELECT
tenant_id,
resource_type,
DATE_FORMAT(usage_date, '%Y-%m') AS month,
SUM(usage_amount) AS monthly_usage
FROM resource_usage
WHERE usage_date BETWEEN '2024-01-01' AND '2024-01-31'
GROUP BY tenant_id, resource_type, DATE_FORMAT(usage_date, '%Y-%m')
ORDER BY tenant_id, resource_type;
不同数据库语法差异
不同数据库在日期处理和分组语法上略有差异,以下是常见数据库的调整方式:
| 数据库类型 | 月度格式化函数 | 示例代码片段 |
|---|---|---|
| MySQL | DATE_FORMAT | DATE_FORMAT(usage_date, '%Y-%m') |
| PostgreSQL | TO_CHAR | TO_CHAR(usage_date, 'YYYY-MM') |
| SQL Server | FORMAT/CONVERT | FORMAT(usage_date, 'yyyy-MM') |
注意事项
- 租户标识字段需要添加索引,提升分组查询的性能,尤其是数据量较大的场景。
- 统计时需要确保租户数据隔离,避免跨租户的数据泄露,查询时可以根据当前登录租户的标识过滤数据。
- 如果资源类型较多,分组结果可能较多,可以根据业务需求增加分页逻辑。
租户数据过滤示例
如果只需要统计当前租户的资源数据,可以在查询条件中增加租户标识过滤:
-- 统计租户tenant_001的资源使用情况
SELECT
tenant_id,
resource_type,
SUM(usage_amount) AS total_usage
FROM resource_usage
WHERE tenant_id = 'tenant_001'
GROUP BY tenant_id, resource_type;