【系统架构师】-案例篇(十四)数据库与分布式

1、规范化

不满足3NF,导致的存储异常

原关系模式

航班(航班编号,航空公司,起飞地,起飞时间,目的地,到达时间,剩余票数,票价)

代理商(代理商编号,代理商名称,客服电话,地址,负责人)

机票代理(代理商编号,航班编号,票价)

旅客(身份证号,姓名,性别,出生日期,电话)

购票(购票单号,身份证号,航班编号,搭乘日期,购票金额)

根据业务,修改后关系模式 机票代理(代理商编号,航班编号,代理商名称,客服电话,票价)

1)数据冗余:代理商名称和客服电话存在于两个关系模式,而且机票代理关系模式中,该代理商代理了多少个航班,则代理商名称和客服电话被重复存储多少次。

2)更新异常:当代理商名称或客服电话变更时,不仅需要修改代理商关系模式,还需要修改机票代理关系模式,否则会造成数据不一致。

反规范化方案

1)增加冗余列:指在多个表中具有相同的属性列,常用来在查询时避免连接操作。

2)增加派生列:指增加的列可以通过表中其他属性列加工计算生成,作用是查询时减少计算量。

3)表重组:如果需要经常查询两个表连接之后的数据,则把这两个表重新组成一个表来减少连接而提高性能。

4)表分割:通过将较大的表分割为多个较小的表来提高查询性能,包括水平分割和垂直分割。

2、不满足3NF存储的不一致解决方案

(1)通过程序实现,当修改代理商关系模式数据时,程序同步修改机票代理关系模式;

(2)通过触发器实现,在代理商关系模式上加修改触发器,当修改代理商关系模式数据时,程序同步修改机票代理关系模式。

三种方案

(1)应用程序同步:指的是通过应用程序在更新数据的同时,同步更新对应的冗余数据,这两个操作会放到同一个事务中,从而保证两个操作的原子性。

(2)触发器同步:触发器是与表事件相关的特殊存储过程,它由执行事件来触发,由数据库管理系统在后台自动执行。常见的方法是在更新数据的表上增加相应事件的触发器,在触发器内容同步更新冗余数据。强一致性

(3)批处理同步:对数据一致性要求不高的场景下。 当更新数据操作执行了一段时间后,根据更新数据进行批量的同步操作,使得冗余数据和更新数据保持一致。

3、仅剩一张机票下,两个代理商的操作如下

1)第一个代理商能够正确售票。第二个代理商查询剩余票数时正确,为l张机票但剩

余票数减一操作时出错,因为该机票已经被第一个代理商售出,此时第二个代理商无票可售。

2)并发操作会带来数据不一致问题具体为:++丢失修改、读脏数据、不可重复读++。

4、读写锁应用

(1)加写锁 (2)加读锁 (3)加写锁 (4)被阻塞(5)得到通知 (6)加写锁

读写锁的缺点:读写锁会造成读写操作的互相阻塞,实际使得用户的操作被串行化,降低了系统的并发性能。设计不好的情况下,可能会出现资源的交叉锁定,形成死锁。

5、分布式数据库

分布式数据库是用计算机网络将物理上分散的多个数据库单元连接起来组成的一个逻辑上统一的数据库。每个被连接起来的数据库单元称为站点或节点。

常见实现技术:读写分离、数据分片、数据索引、数据缓存、负载均衡等。

6、多读少写场景,分布式数据库实现方式

系统应采用的分布式数据库实现方式为++一主多从分布、读写分离++。

原因:在购物网站中,读操作远多于写操作,在原始的数据库中,当写入的时候必须要锁住数据表,当小数据量的时候并不会出现瓶颈问题。当数据量暴增时,读写数据必然会受到很大的影响。如果把读操作和写操作分离开来,性能将大大提高。

6.1、读写分离主从复制的优点

①避免数据库单点故障:主服务器实时、异步复制数据到从服务器,当主数据库宕机时,可在从数据库中选择一个升级为主服务器,从而防止数据库单点故障。

②提高查询效率:根据系统数据库访问特点,可以使用主数据库进行数据的插入、删除及更新等写操作,而从数据库则专门用来进行数据查询操作,从而将查询操作分担到不同的从服务器以提高数据库访问效率。

6.2、基于Mysql binlog分析主从复制的过程

当在从库上启动复制时,首先创建I/O线程连接主库,

主库随后创建Binlog Dump线程读取数据库事件并发送给I/O线程,

I/O线程获取到事件数据后更新到从库的中继日志Relay Log中去,

从库上的SQL线程读取中继日志Relay Log中更新的数据库事件并应用。

6.3、主从复制中同步、异步、半同步区别

(1)同步复制:主数据库需要等待所有备数据库均操作成功才可以响应用户,影响用户体验。这种方式保证了系统的一致性,但牺牲了数据的可用性。

(2)异步复制:当用户请求更新数据时,主数据库处理完请求后可直接给用户响应,而不必等待备数据库完成同步,备数据库会异步进行数据的同步,用户的更新操作不会因为备数据库未完成数据同步而导致阻塞。这种方式保证了系统的可用性,但牺牲了数据的一致性。

(3)半同步复制:用户发出写请求后,主数据库会执行写操作,并给备数据库发送同步请求,但主数据库不用等待所有备数据库回复数据同步成功便可响应用户,也就是说主数据库可以等待一部分备数据库同步完成后响应用户写操作执行成功。

6.4、Redis与Mysql一致性

读数据时先读取Redis中的key,如读到且未失效则返回key对应的数据:

如读不到或key失效,则读取数据库,并同步Redis;

写数据时先写数据库,并设置内存对应的key失效。

相关推荐
小码的头发丝、40 分钟前
Django中ListView 和 DetailView类的区别
数据库·python·django
Karoku0661 小时前
【企业级分布式系统】Zabbix监控系统与部署安装
运维·服务器·数据库·redis·mysql·zabbix
材料苦逼不会梦到计算机白富美1 小时前
golang分布式缓存项目 Day 1
分布式·缓存·golang
想进大厂的小王1 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
Java 第一深情1 小时前
高性能分布式缓存Redis-数据管理与性能提升之道
redis·分布式·缓存
周全全1 小时前
MySQL报错解决:The user specified as a definer (‘root‘@‘%‘) does not exist
android·数据库·mysql
白云如幻2 小时前
MySQL的分组函数
数据库·mysql
荒川之神2 小时前
ORACLE 闪回技术简介
数据库·oracle
ZHOU西口3 小时前
微服务实战系列之玩转Docker(十八)
分布式·docker·云原生·架构·数据安全·etcd·rbac
zmd-zk3 小时前
kafka+zookeeper的搭建
大数据·分布式·zookeeper·中间件·kafka