说明
主要为了展示报表数据
- 1 更灵活的控制报表数据的更新与修改
- 2 兼顾存储与可视化
1 使用FLask(蓝图模式)启动网络服务
2 使用Mysql存储表格数据(通过pymysql和flask sqlalchemy)
当需要从外部灌入数据时,使用pymysql进行数据导入;在flask提供服务时,则使用sqlalchemy方便的获取所需的数据。
1 报表类型
1 假设现在我们能获取一些数据,从这些数据里需要提炼出汇总数据展示(例如行业数据)
2 假设用户可能上传数据,我们计算完成后存入数据库
1.1 汇总表
从聚合的角度看,从原始数据表中使用维度,对变量进行某种汇聚。
- 1 数据表
- 2 维度变量
- 3 统计变量(方法)
- 4 统计结果
可以每种报告一张数据表
字段如下:
id | name | version | report_id | var_id | val | dim1 | dim2 | … | create_time | update_time |
记录id | 简称,主要是为了sqlalchemy展示 | 报告版本(可以刷新) | 报告id,不同的报告对应了不同的统计方法 | var_id 对应统计的变量,使用id的目的是可以灵活重定义名称 | 浮点数值 | 分类维度1 | 分类维度2 | 其他维度,每种报告的维度不一致 | 创建时间 | 修改时间 - 如果当期报告有错误的话 |
对应的report_id 和 var_id可以另外起表存储。
1.2 个体表
id | name | version | report_id | file_id | user_id | var1 | var2 | … | create_time | update_time |
记录id | 简称,主要是为了sqlalchemy展示 | 报告版本(可以刷新) | 报告id,不同的报告对应了不同的统计方法 | 文件id,对应某个上传文件 | 用户id | 指标1的值 | 指标2的值 | 根据不同报表指标数不固定,最好预留三个 | 创建时间 | 修改时间 - 如有错误 |
report_id可以另外起表存储,比较特别的是变量映射表。有一个字段保存var1, var2的字段和原始字段名称映射。
2 表的数据库存储
2.1 是否用映射表
例如,在表中存的不是原始值,而是某个id。然后为这个字段的id另外建立一张表,这个表就是映射表。
什么时候需要用映射表?
- 1 如果记录行(row)可能非常多
- 2 如果字段的具体内容可能会经常修改
另外一个小点是,不要把这些键值做外键关联,万一要删表还挺麻烦的(虽然在狗书中数据对象经常这么关联)。除非关系非常明确,以后也不打算改了,否则最好不要这么做。
我的建议是:把映射表作为静态资源,在服务器启动时载入。
例如,启动时将变量的映射表载入,变为字典。(对应的,有可能需要有个视图函数负责reload,对应静态表偶尔的变动,又不必重启服务)
2.2 横表还是竖表
结构化库由于要“结构化”字段,因此横表收到的字段规划限制较多。如果改为竖表可以增加灵活性,但是会让行数边的比较夸张,并且提取数据时稍微麻烦一点。据说mysql单表的上限大约是5000万条左右,所以要均衡一下。
以分析为主的报表以竖表存储,以事实为主的报表以横表存储。
例如行业汇总数据存竖表,方便随时替换分析。
2.3 存在一张表还是多张表
我觉得应该按照使用的功能和时间两个维度,拆成多个表。
功能上分表有点类似不把鸡蛋放在一个篮子里,互不干涉。而时间上分表也是必然,提高响应速度。
3 迁移与管理
3.1 多个数据源
如果某个表可能来自多个数据源,应该增加一个数据源字段,使用时有可能进行切换和取舍。例如,在某种情况下优先选用x数据源的数据。不过这部分属于主数据整合,逻辑上可以认为放在更早的步骤完成。如果业务上有需求,可以建master_a, master_b之类的,在使用时应该是不需要管处理逻辑的。
3.2 部分迁移
确认迁移的行和列。
首先确认目标列可以兼容当前的数据格式。因为是报表,大部分是浮点数值型变量,应该比较容易达到这个要求。
另外要确认关键的id指标(用来筛选行),用于辨识行的。
通常哪类报表需要迁移?
与某个用户或文件关联的个性化报表需要迁移。汇总型的大不了重新灌一次数据就可以了。
以上基本是原则和方法,以后有机会我补充实例
4 实例(Next 补充)