Nosql 什么是组合存储库和服务总线?

Nosql 什么是组合存储库和服务总线?,nosql,amazon-dynamodb,Nosql,Amazon Dynamodb,我正在学习更多关于NoSQL,特别是DynamoDB的知识。我最近问了一个问题: 在接受答案下的评论中;答案指的是服务总线和组合存储库 Q1)这是服务巴士吗?(请参阅EventListener类): 问题2)什么是组合存储库?它是一个“组合”存储库,即一些方法与多个数据库(SQL Server和DynamoDB)接口 我通常会问回答者,但是我们在另一个问题中开始偏离原来的帖子——回答者提到了这一点。因此,我决定提出另一个问题 我正在考虑使用NoSQL数据库来扩展数据库读取 好主意。听起来你正在走

我正在学习更多关于NoSQL,特别是DynamoDB的知识。我最近问了一个问题:

在接受答案下的评论中;答案指的是服务总线和组合存储库

Q1)这是服务巴士吗?(请参阅EventListener类):

问题2)什么是组合存储库?它是一个“组合”存储库,即一些方法与多个数据库(SQL Server和DynamoDB)接口

我通常会问回答者,但是我们在另一个问题中开始偏离原来的帖子——回答者提到了这一点。因此,我决定提出另一个问题

我正在考虑使用NoSQL数据库来扩展数据库读取

好主意。听起来你正在走一条新的道路。NoSql数据库可以实现出色的读取存储

您引用的描述了要更新的技术 使用NHibernate组合SQL Server和MongoDB——这就是我所说的“组合”(组合)存储库。“组合存储库”不是标准模式。引用作者的话:

当然,理论上,我们可以将所有数据移动到一些NoSQL存储中,但是如果我们不想完全摆脱关系数据库呢?我们如何将它们结合在一起

您已经用
Sql Server
NoSql
数据库为原始问题添加了标签,因此猜测您在

是围绕数据持久性的一个非常常见的抽象层

您提到的“组合”链接专门解决了多对多关系(在Sql中通常称为连接表)的问题,以及存在多个此类关系时的性能影响

在更一般的意义上,作为在NHibernate中提供拦截点的替代方案,您可能/可能没有通过存储库模式进行抽象数据访问

这里有一个超简单(非通用)的C#存储库接口:

为了同时维护这两个数据库,下面是一个“组合”存储库的示例:

public class ComboWidgetRepository : IWidgetRepository
{
     private readonly IWidgetRepository _repo1;
     private readonly IWidgetRepository _repo2;

     public ComboWidgetRepository(IWidgetRepository repo1, IWidgetRepository repo2)
     {
          repo1 = repo1;
          repo1 = repo2;
     }

     public async Task<Widget> FetchWidget(string widgetKey)
     {
          // Just need the one ... first one wins
          return await Task.WhenAny(repo1.FetchWidget(widgetKey), 
                                    repo2.FetchWidget(widgetKey));
     }

     public async Task SaveWidget(Widget toBeSaved)
     {
          // Need both to be saved
          await Task.WhenAll(repo1.SaveWidget(toBeSaved), 
                             repo2.SaveWidget(toBeSaved));
     }
公共类ComboWidgetRepository:IWidgetRepository
{
专用只读IWidgetRepository\u repo1;
专用只读IWidgetRepository\u repo2;
公共组合WidgetRepository(IWidgetRepository repo1、IWidgetRepository repo2)
{
repo1=repo1;
repo1=repo2;
}
公共异步任务FetchWidget(字符串widgetKey)
{
//只需要一个…第一个赢
返回wait Task.whenay(repo1.FetchWidget(widgetKey)),
repo2.FetchWidget(widgetKey));
}
公共异步任务保存小部件(小部件待保存)
{
//两者都需要保存
等待Task.WhenAll(repo1.SaveWidget(toBeSaved),
repo2.SaveWidget(tobesave));
}
上述“组合”存储库可以很好地满足单个系统的需要(还有许多其他方法可以保持两个数据库的同步)

然而,CQRS在企业规模上经常使用(即,您有许多系统,有许多数据库)

只有当您需要在整个企业中分发数据时,我对的评论才有意义

这个概念很简单

  • 命令通过总线排队到事务系统(例如“添加小部件”)
  • 您的系统处理小部件执行事务(例如,将小部件插入数据库)
  • 小部件
    系统随后向总线发布(广播)一条消息,详细说明已添加一个新的小部件(以及所有相关的小部件信息)
  • 企业中对小部件更新感兴趣的其他系统订阅此消息,并将更新其自己的小部件
    读取存储
    表示(例如,将其更新到NoSql数据库或缓存中,并采用对其最有意义的格式)
  • 这样,当用户访问这些其他系统中的任何一个并查看有关“小部件”的屏幕时,系统可以从其自己的读取存储中提供数据,而不必从
    小部件
    系统本身请求数据

+1以获得全面的答案。可以公平地说,组合存储库应该用于新存储库,而NHibernate拦截器/NHibernate事件侦听器应该用于现有存储库吗?您最初的问题是如何将关系数据库模型重复到NoSql文档中,然后事情就从那里开始了。我会d建议从简单开始,使用最简单的方法来保持两个数据库的同步。(出于性能原因,NoSql数据库的用例可能是作为关系数据库的缓存),但随着系统的发展,您会希望将两个存储库解耦(例如,SOLID style)只有当你的应用程序发展到一个系统之外,然后只考虑看CQRS和基于总线的企业。我的阅读告诉我CQRS与一个单一数据库的应用程序相关。毕竟他们有命令和查询。我在这里问了另一个DyDoDB问题:如果你有时间,请看一看。
public class SqlWidgetRepository : IWidgetRepository
{
     public async Task<Widget> FetchWidget(string widgetKey)
     {
         ... Code to use Obtain an NHibernate session and retrieve and deserialize Widget
     }
    ... Other methods here
}   
public class MongoWidgetRepository : IWidgetRepository
{
     public async Task<Widget> FetchWidget(string widgetKey)
     {
        ... Code to connect to a MongoDb secondary and Find() the 
           widget and deserialiaze into Widget
     }
    ... Other methods here
}   
public class ComboWidgetRepository : IWidgetRepository
{
     private readonly IWidgetRepository _repo1;
     private readonly IWidgetRepository _repo2;

     public ComboWidgetRepository(IWidgetRepository repo1, IWidgetRepository repo2)
     {
          repo1 = repo1;
          repo1 = repo2;
     }

     public async Task<Widget> FetchWidget(string widgetKey)
     {
          // Just need the one ... first one wins
          return await Task.WhenAny(repo1.FetchWidget(widgetKey), 
                                    repo2.FetchWidget(widgetKey));
     }

     public async Task SaveWidget(Widget toBeSaved)
     {
          // Need both to be saved
          await Task.WhenAll(repo1.SaveWidget(toBeSaved), 
                             repo2.SaveWidget(toBeSaved));
     }