昨天和我们单位的一位开发人员聊天,关于一个项目,原来程序后端用的数据库是mongoDB sharding,准备迁到PostgreSQL。

迁移过来的话涉及到从非结构化转结构化的过程。
首先说说原来mongoDB里面存储的内容 : 
document1: {用户标识(带字符串数字),用户的消费情况(如业务a,消费多少,业务b消费多少,业务z消费多少)} 
document2: {用户标识(带字符串数字),用户的消费情况(如业务d,消费多少,业务f消费多少)} 
documentn: {....} 
程序数据库的主要操作类型:
1. 用户以前消费过的业务的值得变更,修改“用户的消费情况"这个key的值。
2. 用户以前没有消费过的业务的新增,修改“用户的消费情况"这个key的值。
3. 查询用户的消费情况(单业务,多业务,全业务,总计等)。
转换到PostgreSQL的时候使用用户的标识,在应用层转换为数字,并对这个数字取2的N次方的模。也就是说把用户的数据分割成了2的N次方份。
【注】在这里设计mongoDB sharding和PostgreSQL分区的时候都没有考虑跨库事务和全局事务状态一致。(主要依赖几台服务器的时间同步来做时间点一致的恢复)
大体的方向已经确定了(表分割,分库)。
如4台服务器,将2的N次方个表分布到这4台服务器上。(STANDBY和高可用的情况不在本文讨论)
在确定PostgreSQL里面的表结构的时候,面临一个选择题:
1. 一张表,字段如下 (Static Schema)
userid , appid1_value , appid2_value , appid3_value , appid4_value ... appidn_value , count_value
2. 一张表,字段如下 (Dynamic Schema)
userid , json_text (内容格式appid1_value , appid2_value , appid3_value , appid4_value ... appidn_value , count_value)
3. 每个APPID各一张表,COUNT一张表。表字段如下 (Seperate Schema)
userid , appid_value
userid , count_value
针对在mongoDB里面的三种常用数据库操作,这里的三种设计结构各有优缺点:
1. 用户以前消费过的业务的值得变更,修改“用户的消费情况"这个key的值。
如使用Static Schema,update tbl_static set appidn_value=$1,count_value=$2 where userid=$3; 
优点,count_value和appidn_value在一个事务里面操作,并且一个USERID同时只允许一个更新SQL,原子性得以保证。
缺点,新增APPID时需要变更表结构。某些用户可能成为热点,如同一时间同一个用户频繁提交不同的APPID更新请求(虽然手机上理论上这种情况很少见,但是可能存在攻击行为)。
如使用Dynamic Schema,update tbl_dynamic set json_text=$1 where userid=$2; 
优点,count_value和appidn_value在一个事务里面操作,并且一个USERID同时只允许一个更新SQL,原子性得以保证。
缺点,某些用户可能成为热点,如同一时间同一个用户频繁提交不同的APPID更新请求(虽然手机上理论上这种情况很少见,但是可能存在攻击行为)。

如使用Seperate Schema,begin; update tbl_sperate_appidn set appid_value=$1 where userid=$2;  update tbl_sperate_count set count_value=$1 where userid=$2; 
优点,与上面不同的是如果同一时间同一个用户频繁提交不同的APPID更新请求,这种设计不存在用户热点,但是频繁提交同一个APPID的更新请求还是和前面一样。
缺点,新增APPID时需要增加表。count_value和appidn_value在一个事务里面操作,如果同一时间同一个用户ID还在操作另一个APPID时,可能存在COUNT表的锁等待事件增加。

2. 用户以前没有消费过的业务的新增,修改“用户的消费情况"这个key的值。
如使用Static Schema,update tbl_static set appidn_value=$1,count_value=$2 where userid=$3; 如果返回记录不存在则插入;(乐观考虑)
优点,count_value和appidn_value在一个事务里面操作,并且一个USERID同时只允许一个更新SQL,原子性得以保证。
缺点,新增APPID时需要变更表结构。某些用户可能成为热点,如同一时间同一个用户频繁提交不同的APPID更新请求(虽然手机上理论上这种情况很少见,但是可能存在攻击行为)。

如使用Dynamic Schema,update tbl_dynamic set json_text=$1 where userid=$2; 如果返回记录不存在则插入;(乐观考虑)
优点,count_value和appidn_value在一个事务里面操作,并且一个USERID同时只允许一个更新SQL,原子性得以保证。
缺点,某些用户可能成为热点,如同一时间同一个用户频繁提交不同的APPID更新请求(虽然手机上理论上这种情况很少见,但是可能存在攻击行为)。

如使用Seperate Schema,begin; update tbl_sperate_appidn set appid_value=$1 where userid=$2;  update tbl_sperate_count set count_value=$1 where userid=$2; (悲观考虑,因为COUNT和APPID表在一个事务里面,这里建议考虑悲观情况,以免经常性的事务回滚)(首先要判断count里面有没有USERID,另外还要判断APPID表里面有没有USERID,最后是插入APPID表的动作以及插入或更新COUNT表的动作)

优点,与上面不同的是如果同一时间同一个用户频繁提交不同的APPID更新请求,这种设计不存在用户热点,但是频繁提交同一个APPID的更新请求还是和前面一样。
缺点,新增APPID时需要增加表。count_value和appidn_value在一个事务里面操作,如果同一时间同一个用户ID还在操作另一个APPID时,可能存在COUNT表的锁等待事件增加。

3. 查询用户的消费情况(单业务,多业务,全业务,总计等)。

如使用Static Schema,select appidn_value,...,count_value from  tbl_static where userid=$1;
优点,单业务,多业务,全业务,总计,查询耗费的物理IO一致。
缺点,不能把表分布到不同的物理存储。不能做字段压缩。

如使用Dynamic Schema,select appidn_value,...,count_value from  tbl_dynamic where userid=$1;
优点,单业务,多业务,全业务,总计,查询耗费的物理IO一致。可以做字段压缩。
缺点,每次查询都需要get整个text,可能造成网卡流量的上升(一般流量不存在问题)。不能把表分布到不同的物理存储。

如使用Seperate Schema,多业务查询和全业务查询需要考虑事务隔离度,更加复杂。
优点,可以把表分布到不同的物理存储。
缺点,多业务或全业务查询时需要更多的物理IO请求。
综合考虑后,选择了Dynamic Schema设计。
1. 同一时间同一个用户频繁提交APPID value更新请求。程序设计了黑名单来防止异常用户攻击。
2. 因为可以做字段压缩,三种结构中Dynamic Schema耗费的物理空间最小。
3. 每次查询都需要get整个text,可能造成网卡流量的上升,现在网卡速度都还不错,一般流量不存在问题。
4. 使用上更加灵活,因为TEXT的内容完全由程序定义,用户增加APPID的信息不需要变更结构。

Dynamic , Static or Seperate Schema Design (Convert No-SQL to ORDBMS)相关推荐

  1. 文档(Documents), 字段(Fields), 及模式设计(Schema Design)

    1. 文档(Documents), 字段(Fields), 及模式设计(Schema Design) 1.1 概览 1.1.1 Solr的Schema文件 Solr在schema文件中存储它需要知道的 ...

  2. 原文翻译 - 设计MongoDB架构的6条经验法则 - 6 Rules of Thumb for MongoDB Schema Design: Part 1

    原文作者: William Zola, Lead Technical Support Engineer at MongoDB 原文链接 "虽然我有很多SQL的经验,但是对于MongoDB,我 ...

  3. 物联网新零售项目 售货机“五脏六腑”深度剖析

    第9章 售货机"五脏六腑"深度剖析 课程目标 理解售货机业务 完成嵌入式数据库h2集成开发 完成售货机emqt集成开发 完成售货机和服务器数据同步,价格变动,出货,补货等业务开发 ...

  4. [转]Dynamic and static Rectangle in WPF

    此文转载自:Raj Kumar In geometry, a rectangle is defined as a quadrilateral where all four of its angles ...

  5. 【Java代码】使用 org.apache.ibatis.plugin.Interceptor 拦截器实现全局 mapper.xml 参数注入(可用于切换数据库实例schema+Demo举例源码)

    1. why   项目没有使用MyBatis,进行数据操作时使用的是jdbc中默认的schema,现在项目要加入多租户,同一个数据库下不同租户使用不同的实例schema,这就要在mapper文件内所有 ...

  6. 定义Mybatis拦截器动态切换postgre数据库schema

    背景 随着业务的发展和合规要求,产品数据库将切换到Postgres.之前不同技术域,不同交付工程的数据分库管理的方式切换到PG数据库后将通过分schema管理. ORM继续使用Mybatis,为使用迁 ...

  7. Data Oriented Analysis Design

    前言 ========================================== 偶然的機會裡,看到了呆伯特法則,除了常常捧腹大笑以外,總覺得自 己在軟體界待過以後,看到的現象,其實跟書上寫 ...

  8. 【Android】Android 8 WiFi的自由控制:静态STATIC连接 + 动态DHCP连接

    本文方法不需要jar包,所有的方法齐全,都在两个工具类中了. 3个硬参数 手机型号:Redmi Note5 MIUI版本:MIUI 10 8.8.9开发版本 Android版本:8.1.0 2句话调用 ...

  9. Oracle Schema Objects(Schema Object Storage And Type)

    One characteristic of an RDBMS is the independence of physical data storage from logical data struct ...

  10. 什么是schema?

    目录 1.定义 2.区别 (1)MySQL中的schema (2)PostgreSQL中的schema (3)SQL Server中的schema (4)Oracle中的schema 3.总结 1.定 ...

最新文章

  1. mysql增加布尔字段_如何将布尔字段添加到MySQL?
  2. Jenkins 流水线 获取git 分支列表_使用Jenkins Git参数实现分支标签动态选择
  3. 从Airbnb的发展历程和网易云的大起大落看IT行业创新(第5周课后作业)
  4. Linux引导流程(第二版)
  5. Leetcode: mimimum depth of tree, path sum, path sum II
  6. shell自定义数组元素分隔符
  7. php分享十八七:mysql基础
  8. 造成物联卡那么火爆的原因是什么
  9. 零基础考公务员,备考多长时间最合适?
  10. error C2065: ‘_beginthread‘ : undeclared identifier
  11. win11提示此驱动正在使用中,硬盘格式化不了
  12. GUI(图形用户界面)
  13. 【社区图书馆】《网络工程师的Python之路:网络运维自动化实战(第2版)》
  14. Day02| 第四期-阿里巴巴股票行情分析(一)
  15. 码神-day8-java
  16. 使用vue开发APICloud软件APP的教程
  17. 【汽车总线技术】CAN和CAN FD总线故障诊断
  18. 广州电信新推出的实惠套餐(目前更新时间3月27日,非官方口径,不正确的地方请指出)...
  19. 掌握五点,普通网站的优化不再是什么难事
  20. 新能源车,许家印的雄心,恒大的第二战场

热门文章

  1. 王者荣耀服务器未响应 小米,10月23日小米手机更新王者荣耀失败 小米更新不了新赛季怎么办...
  2. earn the python in hard way习题31~35的附加习题
  3. 移动硬盘无法访问怎么办?还能恢复数据吗?
  4. SCUT校赛130:对抗女巫的魔法碎片(思维)
  5. 大白菜Ghost备份还原系统-人人都会重装系统
  6. 【云原生之Docker实战】使用Docker部署siyuan个人笔记系统
  7. Excel 去除重复行
  8. 深信服技术认证之使用spark进行数据分析示例之拆分字段
  9. 小丁带你走进git的世界三-撤销修改(转)
  10. 【不正经科普】一文读懂“区块链”