浅谈CURD系统和CRQS系统

在网上看到关于这个内容的介绍,就想着自己整理一下,方便观看。

三层架构

先从三层架构开始讲,三层架构(3-tier architecture) 通常意义上的三层架构就是将整个业务应用划分为:界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。区分层次的目的即为了”高内聚低耦合”的思想。在软件体系架构设计中,分层式结构是最常见,也是最重要的一种结构。微软推荐的分层式结构一般分为三层,从下至上分别为:数据访问层、业务逻辑层(又或称为领域层)、界面层。

使用目的

目的主要为了“高内聚低耦合”的思想。三层体系的应用程序将业务规则、数据访问、合法性校验等工作放到了中间层进行处理。通常情况下,客户端不直接与数据库进行交互,而是通过COM/DCOM通讯与中间层建立连接,再经由中间层与数据库进行交互。这样也就导致了我们实际过程中可以分开开发三层(每一层功能相互独立)。

各层说明:

界面层(User Interface layer)
UI(界面表现层):主要是指与用户交互的界面。用于接收用户输入的数据和显示处理后用户需要的数据。
业务逻辑层(Business Logic Layer)
BLL:(业务逻辑层):UI层和DAL层之间的桥梁。实现业务逻辑。业务逻辑具体包含:验证、计算、业务规则等等。
数据访问层(Data access layer)
DAL:(数据访问层):与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。(当然这些操作都是基于UI层的。用户的需求反映给界面(UI),UI反映给BLL,BLL反映给DAL,DAL进行数据的操作,操作后再一一返回,直到将用户所需数据反馈给用户)

CRUD系统

CRUD系统其实是数据库基本操作中的Create(创建)、ReadRetrieve(读取)、Update(更新)、Delete(删除)。CRUD系统主要被用在描述软件系统中数据库或者持久层的基本操作功能。其英文定义是:In computing, CRUD is an acronym for create, retrieve, update, and delete. It is used to refer to the basic functions of a database or persistence layer in a software system。

通常对DB执行的增,删,改,查(CRUD)都是针对的系统的实体对象。如通过数据访问层获取数据,然后通过数据传输对象DTO传给表现层。或者,用户需要更新数据,通过DTO对象将数据传给Model,然后通过数据访问层写回数据库,系统中的所有交互都是和数据查询和存储有关,可以认为是数据驱动(Data-Driven)的。

但传统CRUD存在着一些问题

• 使用同一个对象实体来进行数据库读写可能会太粗糙,大多数情况下,比如编辑的时候可能只需要更新个别字段,但是却需要将整个对象都穿进去,有些字段其实是不需要更新的。在查询的时候在表现层可能只需要个别字段,但是需要查询和返回整个实体对象。
• 使用同一实体对象对同一数据进行读写操作的时候,可能会遇到资源竞争的情况,经常要处理的锁的问题,在写入数据的时候,需要加锁。读取数据的时候需要判断是否允许脏读。这样使得系统的逻辑性和复杂性增加,并且会对系统吞吐量的增长会产生影响。
• 同步的,直接与数据库进行交互在大数据量同时访问的情况下可能会影响性能和响应性,并且可能会产生性能瓶颈。
• 由于同一实体对象都会在读写操作中用到,所以对于安全和权限的管理会变得比较复杂。
这里面很重要的一个问题是,系统中的读写频率比,是偏向读,还是偏向写,就如同一般的数据结构在查找和修改上时间复杂度不一样,在设计系统的结构时也需要考虑这样的问题。解决方法就是我们经常用到的对数据库进行读写分离。 让主数据库处理事务性的增,删,改操作(Insert,Update,Delete)操作,让从数据库处理查询操作(Select操作),数据库复制被用来将事务性操作导致的变更同步到集群中的从数据库。这只是从DB角度处理了读写分离,但是从业务或者系统上面读和写仍然是存放在一起的。他们都是用的同一个实体对象。
要从业务上将读和写分离,就是接下来要介绍的命令查询职责分离模式。

CQRS系统

简单的说,CQRS(Command Query Responsibility Segration即命令查询职责分离)就是一个系统,从架构上把 CRUD 系统拆分为两部分:命令(Command)处理和查询(Query)处理。其中命令处理包括增、删、改。
CQRS最早来自于Betrand Meyer(Eiffel语言之父,开-闭原则OCP提出者)在 Object-Oriented Software Construction 这本书中提到的一种 命令查询分离 (Command Query Separation,CQS) 的概念。CQRS是对CQS模式的进一步改进成的一种简单模式。其它由Greg Young在CQRS, Task Based UIs, Event Sourcing agh! 这篇文章中提出。“CQRS只是简单的将之前只需要创建一个对象拆分成了两个对象,这种分离是基于方法是执行命令还是执行查询这一原则来定的(这个和CQS的定义一致)”。基本思想在于,任何一个对象的方法可以分为两大类:
• 命令(Command):不返回任何结果(void),但会改变对象的状态。
• 查询(Query):返回结果,但是不会改变对象的状态,对系统没有副作用。
CQRS使用分离的接口将数据查询操作(Queries)和数据修改操作(Commands)分离开来,这也意味着在查询和更新过程中使用的数据模型也是不一样的。这样读和写逻辑就隔离开来了。

使用CQRS分离了读写职责之后,可以对数据进行读写分离操作来改进性能,可扩展性和安全。如下图:

主数据库处理CUD,从库处理R,从库的的结构可以和主库的结构完全一样,也可以不一样,从库主要用来进行只读的查询操作。在数量上从库的个数也可以根据查询的规模进行扩展,在业务逻辑上,也可以根据专题从主库中划分出不同的从库。从库也可以实现成ReportingDatabase,根据查询的业务需求,从主库中抽取一些必要的数据生成一系列查询报表来存储。

使用ReportingDatabase的一些优点通常可以使得查询变得更加简单高效:
• ReportingDatabase的结构和数据表会针对常用的查询请求进行设计。
• ReportingDatabase数据库通常会去正规化,存储一些冗余而减少必要的Join等联合查询操作,使得查询简化和高效,一些在主数据库中用不到的数据信息,在ReportingDatabase可以不用存储。
• 可以对ReportingDatabase重构优化,而不用去改变操作数据库。
• 对ReportingDatabase数据库的查询不会给操作数据库带来任何压力。
• 可以针对不同的查询请求建立不同的ReportingDatabase库。
当然这也有一些缺点,比如从库数据的更新。如果使用SQLServer,本身也提供了一些如故障转移和复制机制来方便部署。

CQRS系统优点:

  1. 分工明确,可以负责不同的部分
  2. 将业务上的命令和查询的职责分离能够提高系统的性能、可扩展性和安全性。并且在系统的演化中能够保持高度的灵活性,能够防止出现CRUD模式中,对查询或者修改中的某一方进行改动,导致另一方出现问题的情况。
  3. 逻辑清晰,能够看到系统中的那些行为或者操作导致了系统的状态变化。
  4. 可以从数据驱动(Data-Driven) 转到任务驱动(Task-Driven)以及事件驱动(Event-Driven).

在下场景中,可以考虑使用CQRS系统:

  1. 当在业务逻辑层有很多操作需要相同的实体或者对象进行操作的时候。CQRS使得我们可以对读和写定义不同的实体和方法,从而可以减少或者避免对某一方面的更改造成冲突
  2. 对于一些基于任务的用户交互系统,通常这类系统会引导用户通过一系列复杂的步骤和操作,通常会需要一些复杂的领域模型,并且整个团队已经熟悉领域驱动设计技术。写模型有很多和业务逻辑相关的命令操作的堆,输入验证,业务逻辑验证来保证数据的一致性。读模型没有业务逻辑以及验证堆,仅仅是返回DTO对象为视图模型提供数据。读模型最终和写模型相一致。
  3. 适用于一些需要对查询性能和写入性能分开进行优化的系统,尤其是读/写比非常高的系统,横向扩展是必须的。比如,在很多系统中读操作的请求时远大于写操作。为适应这种场景,可以考虑将写模型抽离出来单独扩展,而将写模型运行在一个或者少数几个实例上。少量的写模型实例能够减少合并冲突发生的情况
  4. 适用于一些团队中,一些有经验的开发者可以关注复杂的领域模型,这些用到写操作,而另一些经验较少的开发者可以关注用户界面上的读模型。
  5. 对于系统在将来会随着时间不段演化,有可能会包含不同版本的模型,或者业务规则经常变化的系统
  6. 需要和其他系统整合,特别是需要和事件溯源Event Sourcing进行整合的系统,这样子系统的临时异常不会影响整个系统的其他部分。
    但是在以下场景中,可能不适宜使用CQRS:
  7. 领域模型或者业务逻辑比较简单,这种情况下使用CQRS会把系统搞复杂。
  8. 对于简单的,CRUD模式的用户界面以及与之相关的数据访问操作已经足够的话,没必要使用CQRS,这些都是一个简单的对数据进行增删改查。
  9. 不适合在整个系统中到处使用该模式。在整个数据管理场景中的特定模块中CQRS可能比较有用。但是在有些地方使用CQRS会增加系统不必要的复杂性。
    关于CQRS详细的可以查看参考文献第一篇。

CQRS 实现方式

CQRS 可以有两种实现方式。
1)CQ 两端数据库共享,只是在上层代码上分离。这样做的好处是可以让我们的代码读写分离,更容易维护,而且不存在 CQ 两端的数据一致性问题,因为是共享一个数据库的。这种架构是非常实用的(也就是我上面画的那种)。
2)CQ 两端不仅代码分离,数据库也分离,然后Q端数据由C端同步过来。同步方式有两种:同步或异步,如果需要 CQ 两端的强一致性,则需要用同步;如果能接受 CQ 两端数据的最终一致性,则可以使用异步。C端可以采用Event Sourcing(简称ES)模式,所有C端的最新数据全部用 Domain Event 表达即可;而要查询显示用的数据,则从Q端的 ReadDB(关系型数据库)查询即可。

总结

CQRS是一种思想很简单清晰的设计模式,他通过在业务上分离操作和查询来使得系统具有更好的可扩展性及性能,使得能够对系统的不同部分进行扩展和优化。在CQRS中,所有的涉及到对DB的操作都是通过发送Command,然后特定的Command触发对应事件来完成操作,这个过程是异步的,并且所有涉及到对系统的变更行为都包含在具体的事件中,结合Eventing Source模式,可以记录下所有的事件,而不是以往的某一点的数据信息,这些信息可以作为系统的操作日志,可以来对系统进行回退或者重放。
参考文献:
https://www.cnblogs.com/yangecnu/p/Introduction-CQRS.html
https://mp.weixin.qq.com/s/-9TS3p7gSvrS3P3vOM81YQ

浅谈CURD系统和CRQS系统相关推荐

  1. OTT系统和IPTV系统不一样吗?有什么区别?

    电视是我们的娱乐生活中占据重要的位置.记得小时候看电视开始的时候是天线只有几个台,后来是有限电视可以看好多台,各地方卫视还有央视的一系列节目.上了大学之后看视频主要是电脑上的各视频网站和手机app,尤 ...

  2. linux执行class文件_「大数据干货」Windows系统和Linux系统中打jar包与导入语句剖析...

    Jar包是Java中的压缩包格式,同Zip格式一样,用来对.class文件统一管理,如下是在Windows系统和Linux系统中不同的打包和执行.class程序的过程. windows: Linux: ...

  3. ios 系统提示框_经验分享:新购买移动硬盘格式化为Windows系统和Mac系统同时可以使用的方法...

    经常使用硬盘的小伙伴们都知道,新买的移动硬盘,要想在Windows系统使用的话是可以直接使用的,因为一般情况下新买的移动硬盘格式是适用于Windows系统的NTFS格式:如果想让该移动硬盘也能在苹果的 ...

  4. OLTP 系统和 OLAP 系统的核心设计思想

    关于 OLTP 系统和 OLAP 系统的核心设计思想 数据存储系统的关于查询的典型操作: -- 第一种需求: 根据 key(1) 找 value(name,age), 单点查询 select name ...

  5. Android 系统(68)---使用Xshell在Windows系统和Linux系统之间进行文件传输

    使用Xshell在Windows系统和Linux系统之间进行文件传输 Windows系统在安装虚拟机centos系统之后,如何进行两者之间的文件传输和互操作,或者如何在Windows端使用Xshell ...

  6. Linux系统和windows系统mysql5.7.32的下载

    linux系统和windows系统开源社区版mysql下载方法前4步相同,不同的是最后一步. 1. 2. 3. 4. 5.linux系统 6.window系统 http://www.taodudu.c ...

  7. 简述Android操作系统和IOS系统的区别;

    软件测试面试题中: 简述Android操作系统和IOS系统的区别: 1.两者运行机制不同:IOS采用的是沙盒运行机制,安卓采用的是虚拟机运行机制. 2.两者后台制度不同:IOS中任何第三方程序都不能在 ...

  8. IOS苹果ipa重签名工具(苹果签名工具,ios签名工具,支持Windows系统和Macos系统)

    此款ios苹果ipa重签名工具支持windows系统和Macos系统,是一款完全免费的IPA签名工具,签名时需要用到p12证书文件和provision描述文件,可以使用ios企业证书.个人证书对IPA ...

  9. 如何快速打通CRM系统和ERP系统,实现业务流程自动化流转

    如何快速打通CRM系统和ERP系统,实现业务流程自动化流转 CRM系统和ERP系统是许多人都熟悉的软件系统,可以说有CRM系统和ERP系统才有一个企业的正常运转.那么为什么要打通跟如何快速打通CRM系 ...

  10. linux系统与window区别,linux系统和windows系统的区别是什么?

    linux系统和windows系统的区别 1.内核不同 Linux操作系统使用Linux内核,Windows操作系统使用NT内核:Linux内核代码开源,NT内核代码闭源,也就是说任何人都可以拿着Li ...

最新文章

  1. DB-MySQL:MySQL 事务
  2. 一分钟了解阿里云产品:先知计划
  3. A novel evolutionary model for constructing gene coexpression networks with comprehensive features
  4. nginx 设置开机自动启动脚本
  5. 我学会了python接下来学什么比较好-我,二本,学会Python后月入上万
  6. tensorflow与keras的关系
  7. QT的QMultiMap类的使用
  8. Hibernate的拦截器和监听器 .
  9. sql 数据库 实例删除
  10. 员工转正述职答辩问什么问题_展风采 创未来 | 记德信地产杭州公司新员工转正述职答辩...
  11. 静态库-动态库混合编译
  12. win10怎么手动修改自己的IP地址
  13. BP神经网络详解+原理
  14. win10清除磁盘写保护
  15. Spring Boot在使用Gradle build命令卡住不动了
  16. 一步步教你Windows配置ISCSI共享存储
  17. HPC平台计算软件依赖, Singularity超级简单
  18. HTML:超文本标记语言
  19. first cdsn day
  20. 底层程序员4年的逆袭之旅:穷屌丝-->小老板

热门文章

  1. charles问题?chls.pro/ssl证书安装后还是出现unknown问题?
  2. python培训班时间 费用-python培训班要多少钱?
  3. Excel读写工具类
  4. (经典)tcp粘包分析
  5. Python表白代码:“ 星光月夜烟花皆归你,我也归你”
  6. 【论文阅读】Enhancing Underwater Imagery using Generative Adversarial Networks
  7. Oracle 11g安装过程中提示先决条件检查不通过的解决方法
  8. 云信IM服务端API调用(THINKPHP版)
  9. ios云信不能全屏_网易云信-新增自定义消息(iOS版)
  10. 微信JS-SDK实现自定义分享功能,分享给朋友,分享到朋友圈及QQ自定义分享--微信分享