【问题标题】:What is a Combo Repository and a Service Bus?什么是组合存储库和服务总线?
【发布时间】:2018-04-16 09:14:43
【问题描述】:

我正在学习有关 NoSQL 的更多信息,特别是 DynamoDB。我最近问了这个问题:Mapping database structure from SQL Server to DynamoDB

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

Q1) 这是服务总线吗? (参见 EventListener 类):http://enterprisecraftsmanship.com/2015/05/06/combining-sql-server-and-mongodb-using-nhibernate/

Q2) 什么是 Combo 存储库?它是“组合”存储库吗,即某些方法与多个数据库(SQL Server 和 DynamoDB)交互。

我通常会问回答者,但是我们开始从另一个问题中的原始帖子转移 - 回答者提到了这一点。因此我决定再问一个问题。

【问题讨论】:

    标签: nosql amazon-dynamodb


    【解决方案1】:

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

    好主意。听起来您正在走Command Query Responsibility Segregation(CQRS) 的道路。 NoSql 数据库是优秀的读取存储。

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

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

    您已经使用Sql-ServerNoSql 数据库标记了您的原始问题,所以猜测您在Polyglot space

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

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

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

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

    public interface IWidgetRepository
    {
         Task<Widget> FetchWidget(string widgetKey);
         Task SaveWidget(Widget toBeSaved);
    }   
    

    假设我们已经有一个 SqlRepository:

    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
    }   
    

    您也可以选择提供MongoDb 实现

    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));
         }
    

    上述“组合”存储库可以很好地满足单个系统的需求(还有许多其他方法可以使两个数据库保持同步)。

    然而,CQRS 经常用于企业规模(即您有许多系统和许多数据库的地方)。

    我对@9​​87654325@ 的评论只有在您需要在整个企业中分发数据时才有意义。

    概念很简单

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

    【讨论】:

    • +1 以获得全面的答案。是否可以公平地说组合存储库应该用于新存储库而 NHibernate 拦截器/NHibernate 事件侦听器应该用于现有存储库?
    • 您最初的问题是如何将关系数据库模型重复到 NoSql 文档中,事情从那里开始发展。我建议从简单的开始,用任何对你来说最简单的方法来保持两个数据库的同步。 (出于性能原因,NoSql 数据库的用例可能是作为关系数据库的缓存)但是,随着系统的增长,您将希望分离两个存储库(例如 SOLID 样式)以保持可测试性。只有当您的应用超越了一个系统时,才考虑考虑基于 CQRS 和总线的企业。
    • 我的阅读告诉我,cqrs 与具有单个数据库的应用程序相关。毕竟他们有命令和查询。
    • 我在这里问了另一个 DynamoDB 问题:stackoverflow.com/questions/47269542/…。有时间请看一下。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-16
    • 2011-04-02
    • 2011-02-13
    • 1970-01-01
    相关资源
    最近更新 更多