Database design 混合数据库系统:NoSQL用于数据,SQL用于关系。最佳实践?

Database design 混合数据库系统:NoSQL用于数据,SQL用于关系。最佳实践?,database-design,nosql,database,Database Design,Nosql,Database,我正在构建一个应用程序,它的数据库系统将是至关重要的,并且需要具有可扩展性,因为它的所有价值都在数据中 我正在制作一个现场投票系统 我对SQL和MongoDB很熟悉,所以这几乎不是一个决定因素(尽管我现在更喜欢MongoDB结构和JS:) 但从我在网上读到的一切来看,我仍然对我的决定感到不安 我想做的是结合两者的优点: 拥有对象(用户、项目、注释等)的noSQL文档 为关系(表用户项、用户注释等)创建SQL表 每当有投票或在固定时间间隔内复制noSQL文档中的投票结果(以提高投票结果显示的速度

我正在构建一个应用程序,它的数据库系统将是至关重要的,并且需要具有可扩展性,因为它的所有价值都在数据中

我正在制作一个现场投票系统

我对SQL和MongoDB很熟悉,所以这几乎不是一个决定因素(尽管我现在更喜欢MongoDB结构和JS:)

但从我在网上读到的一切来看,我仍然对我的决定感到不安

我想做的是结合两者的优点:

  • 拥有对象(用户、项目、注释等)的noSQL文档
  • 为关系(表用户项、用户注释等)创建SQL表
  • 每当有投票或在固定时间间隔内复制noSQL文档中的投票结果(以提高投票结果显示的速度)
我看到的最大优势是:

  • 当查询文档(例如,用户显示其个人资料)时,我拥有NoSQL的所有优点(速度、一处到位、模式灵活性等)
  • 在进行统计(例如投票数)时,我拥有SQL的所有优点
  • 并行化:我可以在SQL中获取投票,并在异步模式下获取文档
  • 读得快,写得慢(这对我来说并不重要)
  • 关系的完整性始终得到维护
  • 我的问题是:

    • 这样做是一种好的做法吗?网络似乎对此很害羞
    • 即使在高分贝负载下,我也在优化花生吗?(将文档获取与完整SQL和查询(如select*from表,其中primary_key=XXX)进行比较)

    如果您喜欢将NoSQL数据库与RDBMS结合使用的唯一原因是为了提高速度和灵活性,我建议您改用缓存服务器(如Memcache)。您可以使用sql语句构建文档/结果,并使用单个键值将其存储在memcache中,以便以后检索。它比MongoDB更容易实现。但是,如果您真的只想通过使用键进行文档查找,或者计划对文档使用更复杂的查询,那么这当然取决于您的需求。

    我想提出另一个建议,即对对象和关系进行建模,以实现可伸缩性

    值得思考的是:

  • 正如您所说,在像MongoDB这样的文档数据库中对实体/对象进行建模
  • 将关系存储在像Titan或Neo4j这样的图形数据库中。在我看来,这些系统更适合存储复杂的关系。您可以轻松地遍历许多复杂关系,然后在图中找到目标节点/顶点时,可以从Mongo加载文档
  • 考虑像Riak这样的东西,它是一个NoSQL文档存储,文档之间也有链接(关系)。他们建议不要使关系过于复杂,但可以在不需要其他系统的情况下将文档链接在一起
  • “最佳实践”是一个可怕的术语——它经常被用来证明直觉的正确性,“我们总是这样做的”,或者其他偏见

    但是,您描述的解决方案有很多优点(您提到了一些),但也有一些明显的缺点,主要是因为您将问题域的知识分散在两个不兼容的数据存储中,这为复制和不一致性提供了很多机会

    例如,NoSQL系统和数据库之间可以共享给定用户由某个标识符标识的知识。如果一个系统删除该用户,另一个系统将处于不一致状态。给定用户的配置文件将在两个系统中拆分,并且两个系统都没有完整的图片;你需要很多内务同步代码

    在您的平台上工作的开发人员需要这两个技术堆栈方面的专业知识——想象一下,试图调试为什么给定用户的评论计数似乎不正确

    现在有两个故障点-如果NoSQL或SQL数据库出现故障,则整个系统将崩溃。失败可能并不意味着崩溃——它还可能意味着性能问题、升级问题或备份问题

    软件解决方案有多个系统,每个系统都拥有一部分数据,这种情况并不少见,通常是按照业务领域划分的(CRM系统知道您的个人资料,支付系统知道您的信用卡详细信息,电子商务系统知道您订购了什么);沿着技术路线拆分部门将创建一个具有多个故障点的复杂体系结构


    我不认为好处大于缺点。

    7年后,我开始提出我自己的问题,感觉现在我可以帮助过去的我了

    今天,我要去

    这允许仍然有表、关系和索引,它们对于理解和原子性非常重要,同时还有
    users
    表中的可扩展字段,如
    identity
    字段,看起来像:

    identity {
      firstName: "John",
      lastName: "Doe",
      address: "5 example st",
      postCode: "XXX",
      city: "Example city"
    }
    
    这是可以查询的,比如:
    select*from users u,其中u.identity->>lastName='Doe'
    (语法不是100%确定)


    虽然一开始这可能很令人惊讶,但它工作得很好。最好是当ORM包含对这些类型的开箱即用支持时,比如等等。

    如果我理解正确,您想像使用某种缓存一样使用MongoDB吗?从您描述的内容来看,我认为这不是一个坏主意,您只需确保MongoDB在应用层与RDBMS保持一致(基本上提高代码复杂度以提高速度)缓存复杂查询,我可能会使用memcached,并且我还可以有一个临时表来存储计算结果。在我的例子中,我还对使用文档来描述我的数据类(例如用户)感兴趣,以保持数据的灵活性、速度和格式。