软考2021高级架构师下午案例分析第4题:关于反规范化设计、数据不一致问题

某医药销售系统采用MySQL和Redis混合架构,初期因规范化设计导致查询性能下降。刘工提出反规范化,增加冗余列以提高查询效率,如在药品表中包含供应商信息和库存。王工指出反规范化可能导致数据不一致,建议使用触发器解决。系统利用Redis实现热销药品排名,选择ZSet数据类型,并需解决Redis与MySQL的数据同步问题,常见方案包括实时同步、异步队列和工具如Canal。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【说明】

​ 某医药销售企业因业务发展,需要建立线上药品销售系统,为用户提供便捷的互联网药品销售服务、该系统除了常规药品展示、订单、用户交流与反馈功能外,还需要提供当前热销产品排名、评价分类管理等功能。

​ 通过对需求的分析,在数据管理上初步决定采用关系数据库(MySQL)和数据库缓存(Redis)的混合架构实现。

​ 经过规范化设计之后,该系统的部分数据库表结构如下所示:

​ 供应商(供应商ID,供应商名称,联系方式,供应商地址);

​ 药品(药品ID,药品名称,药品型号,药品价格,供应商ID);

​ 药品库存(药品ID,当前库存数量);

​ 订单(订单号码,药品ID,供应商ID,药品数量,订单金额)。

【问题1】

​ 在系统初步运行后,发现系统数据访问性能较差。经过分析,刘工认为原来数据库规范化设计之后,关系表过于细分,造成了大量的多表关联查询,影响了性能。例如当用户查询商品信息时,需要同时显示该药品的信息、供应商的信息、当前库存等信息。

​ 为此,刘工认为可以采用反规范化设计来改造药品关系的结构,以提高查询性能。修改后的药品关系结构为:

​ 药品(药品ID,药品名称,药品型号,药品价格,供应商ID,供应商名称,当前库存数量);

​ 请用 200 字以内的文字说明常见的反规范化设计方法,并说明用户查询商品信息应该采用哪种反规范化设计方法。

答案:

常见反规范化技术如下:

(1)增加冗余列:在多个表中保留相同的列,通过增加数据冗余减少或避免查询时的连接操作。

(2)增加派生列:在表中增加可以由本表或其他表中数据计算生成的列,减少查询时的连接操作并避免计算或使用集合函数。

(3)重新组表:如果许多用户需要查看两个表连接出来的结果数据,则把这两个表重新组成一个表来减少连接而提高性能。

(4)水平分表:根据一列或多列数据的值,把数据放到多个独立的表中,主要用于表数据规模很大、表中数据相对独立或数据需要存放到多个介质上时使用。

(5)垂直分割表:对表进行分割,将主键与部分列放到一个表中,主键与其他列放到另一个表中,在查询时减少 I/O 次数。

用户查询商品信息采用的是增加冗余列的方式。

【问题2】

​ 王工认为,反规范化设计可提高查询的性能,但必然会带来数据的不一致性问题。请用 200 字以内的文字说明在反规范化设计中,解决数据不一致性问题的三种常见方法,并说明该系统应该采用哪种方法。

答案:

解决数据不一致性问题的三种常见方法:批处理维护、应用逻辑、触发器。

(1)批处理维护:指对复制列或派生列的修改积累一定的时间后,运行一批处理作业或存储过程对复制或派生列进行修改,这只能在对实时性要求不高的情况下使用。

(2)应用逻辑:要求必须在同一事务中对所有设计的表进行增、删、改操作。用应用逻辑来实现数据的完整性风险较大,因为同一逻辑必须在所有的应用中使用和维护,容易遗漏,特别是在需求变化时,不易于维护。

(3)触发器:对数据的任何修改立即触发对复制列或派生列的相应修改。触发器是实时的,而且相应的处理逻辑只在同一地方出现,易于维护。一般来说,是解决这类问题比较好的办法。

该系统应该采用触发器。

【问题3】

​ 该系统采用了 Redis 来实现某些特定功能(如当前热销药品排名等),同时将药物关系数据放到内存以提高商品查询的性能,但必然会造成 Redis 和 MySQL 的数据实时同步问题。

(1)Redis 的数据类型包括 String、Hash、List、Set 和 ZSet 等,请说明实现当前热销药品排名的功能应该选择哪种数据类型。

(2)请用 200 字以内的文字解释说明解决 Redis 和 MySQL 数据实时同步问题的常见方案。

答案:

(1)ZSet

(2)一、对强一致要求比较高的,应采用实时同步方案,即查缓存查不到再去 DB 查询,然后保存到缓存;更新缓存时,先更新数据库,再将缓存的设置过期(建议不要去更新缓存内容,直接设置过期)。

二、对于并发程度较高的,可采用异步队列的方式同步,可采用 kafka 等消息中间件处理消息生产和消费。

三、使用阿里的同步工具 cannal,cannal 实现方式是模拟 mysql slave 和 master 的同步机制,监控 DB binlog 的日志更新来触发缓存的更新,此种方法可以解放程序员双手、减少工作量,但再使用时有些局限性。

四、采用 UDF 自定义函数的方式,面对 mysql 的 API 进行编程,利用触发器进行缓存同步。

(补充:UDF(User-Defined Function)用户定义函数,用于在数据库中自定义函数使用。)

整理完毕,完结撒花~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不愿放下技术的小赵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值