我C,一个库里Curry几百个表,这谁受得了?

2023-11-30 13:32

本文主要是介绍我C,一个库里Curry几百个表,这谁受得了?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

随着业务越来越复杂,数据量越来越大,并发量越来越大,数据库的性能越来越低。好不容易找运维申请了两台机器,让DBA部署了几个实例,想把一些业务库拆分出来,却发现一个库里几百个表,拆不出来,扩不了容,尴尬!

 

因为数据库强关联在一起,无法通过增加数据库实例扩容,就是一个耦合的典型案例。

 

什么样的场景会出现这类耦合?

举个栗子。

有一个公共用户数据库DB_USER,里面table_user存放了通用的用户数据:

table_user (uid, name, passwd, …)

 

在数据量比较小,并发量比较小,业务还没有这么复杂的时候,为了提高资源利用率(程序员才没有考虑什么资源利用率,更多的是图方便),业务A把用户个性化的数据也放在这个库里:

table_A(uid, A业务的个性化属性)

 

业务A有一个需求,即要展现用户公共属性,又要展现业务A个性化属性,程序员经常这么实现的:

select * from table_user, table_A

      where table_user.uid = table_A.uid

      and table_user.uid = $uid

 

初期关联查询没有任何问题,单条记录访问,命中索引,一次查询所有数据,简单高效。

 

如何产生各业务数据耦合?

通过join实现业务,导致通用表table_user和业务表table_A必须存在于一个数据库实例里。

如果业务B也这么做,业务C也这么做,会导致公用业务,业务A,业务B,业务C都必须存在于一个数据库实例里

会产生什么潜在问题呢?

假如A业务线上线了一个新功能,不小心进行了全表扫描,导致数据库CPU100%,数据库实例性能下降,由于实例共用,通用业务,业务B和业务C都会受影响。

 

即某个业务线的数据库性能急剧下降导致所有业务都受影响,这种耦合,历史总是惊人的相似:

 - 业务B的大boss在群里首先发飙:“技术都干啥了,怎么系统挂了”

 - 业务B的rd一脸无辜:“业务A上线了,所以我们挂了”

额,然而,这个理由,好像在大boss那解释不通…

 - 业务B的大boss:“赶紧加几台机器,拆分开”

 - 业务B的rd一脸无奈:“加机器加实例也扩容不了”

- 业务B的大boss对业务2的rd吼道“还想甩锅,拖出去祭天”

 - ...

唉,加了几台机器,加了几个实例,然而并没有什么卵用,都耦合在一个实例里,完全扩不了容。

 

那,如何解除公共数据库与业务数据库的耦合?

第一步:公共数据访问下沉服务化。

还是上面的例子,当公共的user数据访问服务化之后,依据服务化的原则:

(1)业务层只能通过服务RPC接口访问数据;

(2)底层user库属于user服务私有;

(3)任何上游不允许跨过服务访问底层的user库;

第二步:垂直拆分,个性化数据访问上浮。

原来业务方:通过join一次性获取通用的数据和个性化的业务数据数据。

服务化+垂直拆分后,变成两次访问:

(1)一次取得业务数据(业务可以直接调用自己的数据库,也可以自己做业务服务调用RPC接口);

(2)一次取得共性数据(调用通用的RPC接口);

两种方式相比:

(1)之前的方式其实业务代码可能会更简单一些,因为它是将这个业务逻辑放在了SQL语句中,但是导致数据库耦合在了一起;

(2)后面这种方式就是业务的代码会更复杂,会变成多次访问,将原来在SQL中进行的逻辑计算变成业务代码中的逻辑计算,但是数据库解耦了;

业务复杂,数据量大,并发老大,对扩展性要求更高的架构,一定是后者。

此时各业务有自己的库,公共有公共的库:

(1)早期:可以放在一个数据库实例里;

(2)后期:可以很容易地通过新增数据库实例,把user库或者业务A/B/C的库拆分出来,实现增加机器增加实例就实现扩容;

个性业务数据访问垂直拆分,共性数据访问服务化下沉,只是一个很小的优化点,但对于数据库解耦却是非常的有效。

希望大家每天收获一点点,这样架构就能美好一点点。

你见过一个库里耦合了几百个表吗?

那帮转下。

推荐文章

《每秒100W次的计数,架构这样设计》

《数据库软件架构,到底要设计些什么》

《拷贝代码,居然还有这等好处?》

《没钱就是没钱,那不是吃苦》

这篇关于我C,一个库里Curry几百个表,这谁受得了?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/437219

相关文章

GD32固件库里时钟配置时的神秘代码?高频切低频时芯片会发生什么

在GD固件库的时钟配置函数里看到这样一段神秘代码,研究分析后不得不佩服原厂固件库里的细节处理: 查看定义是一段代码,对AHB 2分频后延时了一段时间: 在这段代码后面可以看到程序将RCU_CFG0和RCU_CFG1两个时钟寄存器做了复位: 如果是程序复位启动后第一次执行这段代码,应该是没有什么意义的,但产品设计时一般都会有一个BootLoader和APP两段程序,当BootLoa

利用dmesg和addr2line来对(动态库里的)段错误进行调试

工作中,我们在varnish的基础上,利用vmod机制,实现了一个可以定制策略,且策略可自动加载而不需重新启动引擎的cache(平时,大家对varnish的利用,cache策略都定义在一个vcl配置文件中,每次对策略进行修改,都需要重新启动varnish,从而使得策略生效,且当部署在varnish后面的站点很多时,不方便对每站点的cache策略进行个性化的定制),这里各种策略的控制以及加载都实现在

库里和字母哥对待每一天的方式很相似 他们都想成最佳球员

直播吧地址:www.wfzkbzj.com 3月3日讯 近日,尼克斯球员迪文岑佐在《Roommates Show》节目中谈到前队友库里和字母哥。 迪文岑佐表示:“库里和扬尼斯肯定有很多不同点,但他们对待每一天的方式是相似的,他们想要成为NBA中最强的人,他们想要成为队内最好的球员。 “上赛季(在勇士)我们训练都很努力,但库里完全是在另一个层级,他的投入很疯狂。我和扬尼斯当了4年队友,

webdriver库里的常用 API

1、webdriver 库里的常用 API 一、appium-python-client 中 webdriver 库里的常用 API 获取当前应用的包名和启动名 driver.current_package # 获取当前应用包名driver.current_activity # 获取当前界面启动名 关闭当前 APP driver.close_app() # 这是一个方法,不是属性

【问题记录】Unity莫名其妙的几百个报错,原来是许可证过期了

报错: Assertion failed on expression: 'm_ErrorCode == MDB_MAP_RESIZED || !HasAbortingErrors()' Asset database transaction committed twice! Assertion failed on expression: 'errors == MDB_SUCCESS ||

使用sql语句获取SQL server库里所有表的表名,注释,行数

select * from (SELECT     t.name,schema_id,     SCHEMA_NAME(schema_id)+'.'+t.name AS 表名,       c.value AS 注释   FROM        sys.tables AS t   LEFT JOIN        sys.extended_properties AS c

javascript函数式编程之curry化

函数式编程是一种编程范式(编程思想,不要以为有啥模板),主要思想是将运算过程尽量写成一系列嵌套的函数。举个例子 //声明式let d = a + b + c * d;//函数式let d = add(a,add(b,mul(c,d))) 例子没有啥难度吧,那么函数式编程的函数和数学的函数有什么关系呢,其实函数式编程的函数就是数学里的函数