NoSQL的反模式的文档数据库

我们的关系数据库模式设计了一套完整的解决方案,但它没有这些。半年前,我读的书SQL反模式开始注意到,有一个NoSQL计数器模式一个好的反模式可以在我们的架构设计,告诉那里的陷阱和悬崖are.nosql往往声称是无模式时,它是宣传,这使得它的误解,它不需要设计模式。但是如果你不知道需要设计架构,陷阱总是在黑暗中我们总结了一些其他人的,有了你的设计方案错误深深的痛苦。

最主流的NoSQL数据库的文档数据库,内存数据库,键值数据库。三个代表是MonDB,HBase和Redis。如果NoSQL作为武器,它可以(MySQL是一个关系数据库中,一个典型的涉及的比较:>)

MySQL产生较早的成熟与灯的潮流。虽然没有大的改善,新兴的互联网使用最多的数据库。像传统的菜刀,结构简单,一直是数百年来改善。在不影响生产的每种刀,只要有一,可以在kitchen.mysql处理大部分事务是相同的,其核心是稳定的。但项、表、备份、监控、等一应俱全。means.mondb是一个新事物,提供更灵活的架构,封顶,收集,异步提交、区位指数五华十的功能。就像一把瑞士军刀,它不仅可以作为一把刀,而是一个瓶盖和一个指甲刀,但他并没有比MySQL,因为它缺乏时间。首先,系统本身的稳定性,二是开发、运行和维护需要更多的经验是popular.hbase是欺负大象的士兵。在Hadoop的生态环境,可以有很好的可扩展性。但就像士兵一样,用户需要有一个象(Hadoop)开车送他。Redis是关键值存储的代表,且功能简单。提供随机数据存储。像酒吧,日有没有多余的结构,但它是,因此,其可扩展性特别好。Goku的手吧,能刺破天空,可以压缩成小针,增益和损失的文档数据库

关系模型试图将数据库模型与数据库实现分离开来,允许开发人员脱离底层数据,但我认为关系模型在某些应用场景中存在弱点,现在必须面对它。

SQL的弱点1:加入必须的支持。由于数据的不可重复性,所以使用一个范式的关系模式是大量的加入不可避免的。如果你在加入,这是一个很好的表与较小的内存比记忆。但如果一个大型表的联接或表分布在多台机器上,加入是performance.sql弱点两噩梦:计算与存储的耦合关系模型,作为一个统一的数据模型,可以用于数据分析和在线业务。但这些都强调高吞吐,强调低延迟,已形成了一种完全不同的结构。明显不当的抽象与这套模式是,Hadoop是针对计算的部分lation.mondb,redis等网上业务。都抛弃的关系模型。

这两个噩梦。文献数据库的主要目的,如mondb,是放弃加入适应网上业务提供更丰富的数据结构。当然不是mondb不能加入,不能用来做数据分析,讨论问题,只是不同的人,不同的看法。因此,文件数据库不比关系型数据库更强大。由于加入了微弱的支持,功能会弱得多。当设计一个关系模式,它通常需要考虑数据的直接关系和定义数据模型,并在设计文件的数据库模型,你需要考虑的是如何应用的。因此,它是更难设计文献数据库,架构,比设计一个关系模型。此外,由于文档数据库事务的支持较弱,NoSQL只是提供了一个行锁。这也使得设计方案更加困难。有很多注意文献数据库的使用。本文只关注模型设计的部分。

反模式1:惯性思维/跟随关系模型

关系模型是数据存储的一个经典模型,并用数据模型范式的好处是非常明显的。然而,因为文档数据库不支持加入(包括外键约束,外键关系密切),使用关系模型的习惯有时是有问题的。我们需要利用文档数据库提供了丰富的数据处理模型。

值得一提的是,文档数据库和关系模型的设计是不同的,它是灵活多样的,对于同一种情况,有多种模型可以工作,没有绝对意义上的最佳模型。

下图是关系模型和文档模型的比较。


关系模型与文档模型

这个博客的数据模型有博客、用户和其他表格,左边是一个关系模型,右边是一个文档模型,这个文档模型不完全合理。它可以被描述为一个两方面的教科书如下。

问题1:对多对多关系表症状的描述:文档数据库存储在纯关系表中,例如:





身份证件
user_id
blog_id













这样的表在关系模型中是不合适的,因为id非常冗余,可以用一个联合主键来解决,但是在文档数据库中,由于需要强制一个主键,所以必须进行这样的设计。

不好的地方:

破坏数据完整性。由于ID是主键,没有约束的数据模型以确保重复的user_id,blog_id对是不存在的。一旦数据是重复的,这是一个更新和删除问题。指数太多。因为这是一个关系表,必须建立索引在user_id和blog_id分别影响性能。

解决方案:文档数据库的使用通常处理多对多的方法,而不是建立关系表,而不是在一个文档中添加一个列表字段(如用户)。





user_id
user_name
blog_id { }
......



满意的
0,1
......



玫瑰
1,2
......





问题二:一对多关系和多对一症状之间没有区别:关系模型不区分一对多和多对一。对于文档数据库,关系模型只有一对多:





comment_id
user_id
内容
......




NoSQL的反模式是一个很好的文章
......




是啊
......





如果整个模型是一对多对的关系,有必要对它进行反思。

不好的地方:

附加指标。如果客户已经知道user_id,你需要获取用户信息和评论信息,你需要执行两个查询的查询需要使用索引,在客户自己的加入可能会有潜在的性能问题。

解决方案:最核心的问题是已知的user_id查询表,或已知的comment_id查询两张彪。如果comment_id是已知的,这样的设计是合理的,但如果它是已知的,user_id是查询,它是把关系在用户表更合理。





user_id
user_name
comment_id { }
......



满意的
0,1
......



玫瑰
1,2
......





这样的设计可以避免索引,同样的,对于多个到多个,可以通过合理地安排字段的位置来避免索引。

何处正确使用:

关系模型是一种非常成功的数据模型,很好地利用了它,但是由于文档数据库的特点,需要进行一些调整,使得数据模型不能是最优的,但具有最好的灵活性,也有利于关系数据库的转换。

反模式二:引用客户端到处连接

Symptoms: the database design is full of xx_id word ends and requires a large number of manual Join operations when querying.It's about this antipattern.As mentioned in the relationship model of the blog mentioned above, if the blog_id query comments is known, you need to perform at least 3 queries and manually Join.

不好的地方:

手动加入,麻烦而且容易出错。文档数据库不支持加入和没有外国的重要保证。所以你需要在客户端连接,这样的操作是软件开发更加复杂。由于没有对外担保的钥匙,也不能保证得到的ID已在数据库中数据。它易于判断和犯错误的时候,与他们打交道。多查询。如果引用太多,查询需要多个查询来找到足够的数据。原始文档数据库是非常快的,但由于多个查询,它增加了压力,数据库,和时间让所有的数据也增加,事务处理是乏味。在一般情况下,文档数据库不支持G一般的交易,只行锁的支持。如果文档数据库有多个连接。在插入时,事务的处理是一个噩梦。在一个文档数据库事务需要使用行锁和大量处理。它太繁琐,有兴趣的读者可以搜索。

解决方案:适当使用内联数据结构。由于文档数据库支持更复杂的数据结构,可转换为内联数据没有新表。这可以解决上述的一些问题,这是一个建议的解决方案。像上述博客的例子。五表简化为两表。当它使用内联吗有人说

使用内联可以解决阅读性能问题,并显著减少查询的数量。它可以简化数据模型,简化表之间的关系,而不会影响灵活性:

文档数据库将由多个应用程序在使用场景的范例中使用,因为数据库设计不能估计多个应用程序和将来的查询,因此需要很大的灵活性。

反模式三滥用内联无止境的麻烦未来

这个问题阻碍了查询的内联症状:经常查询一些内联字段并丢弃其他字段。

不好的地方:

没有身份的约束:没有身份约束使用内联字段和参考。所以它不能由ID(主键),如果你经常需要操作的内嵌对象的孤独,它会很不方便。指数泛滥:如果内联字段进行查询,索引是必要的。这是可能的因为指数洪水。性能浪费:大多数文献数据库实现在线存储,这意味着,即使只有一个字段进行查询,数据库需要从磁盘中删除整行。如果该字段是足够小的文件是足够大的,这是很不合算的。

解决方案:如果出现上述问题,可以考虑使用引用而不是内联。内联功能的主要目的是提高性能。如果业绩不上升和回落,这是毫无意义的。如果有一个强大的性能要求,重复数据可以考虑,和相同的数据也在桌上,在内联字段引用。这可以结合内联和参考的优点。缺点是数据重复,和维护将更麻烦。

问题无限扩大两内联症状:列表、地图的类型的内联领域不断扩大,并没有限制。就像博客的内联字段注释前面所提到的,如果没有限制的数量为每个博客评论,评论将无限膨胀。光性能的影响,并重插入失败。





blog_id
内容
评论{ }
......




NoSQL的反模式是一个很好的文章,是的,无限的增长…
......



不好的地方:

插入失败。每个记录的文档数据库的最大大小,也有最好的建议的尺寸。一般不超过4米。比如刚才提到的例子,如果它是一个受欢迎的博客,审查的尺寸为4m以上。文件将不会同时更新,并新的评论不能插入阻力性能。由于该内联领域扩张,其规模将远远超过其他地区,影响其他部件的性能。因此,记录的大小变化频繁,并有可能在文件数据库的数据文件是一个很大的碎片。

解决方案:设置最大数量或使用引用。作为博客和评论的一个例子,评论可以从博客中剥离到一个表中。如果考虑性能,可以在blog表中创建一个新字段,比如最新的评论。这既保证了性能,又防止了扩展。





blog_id
内容
last_five_comment { }
......




NoSQL的反模式是一个很好的文章,是的,最5。
......



问题三无法维护的内联症状:DBA希望单独维护一个内联字段,但不能这样做。

不好的地方:

这是难以管理的权威。对于数据库的最小权限管理粒度表。如果内联技术应用,这意味着内联必须与其他领域相同的权限管理,有没有办法把它藏在分贝水平。很难把手表。如果你找到一张桌子的大小,你需要把表。这个时候更纠结。如果一刀切,部分关键的选择;该指标的失败将是一个问题。如果你觉得这是断成两表,它将工作做好,这是内联的过度使用。备份是很困难的。在关系数据库中的每个表都有一个不同的备份策略。但如果内联,这种备份是做不到的。解决方法:当设计一个数据库SE模型,它需要维护操作,特别是内联字段不需要单独维护,需要与操作和维护协商。如果内联字段有单独的维护需求,可以将其拆分为引用。

四盯死内联症状中的应用:应用程序可以运行在数据库很好。但是,当新的应用程序连接,它会很麻烦。查询是在设计时考虑了数据模型,所以当新的应用和新的查询连接,很难用原始模型。

不好的地方:

很难获得新的应用。访问是困难的时候,新的应用程序试图使用相同的数据库,因为查询是不同的,你需要调整的数据模型来适应。但调整模式会影响原有的应用程序,很难整合。不同关系数据库可以集成在一起使用。但文档数据库,虽然功能可以互补,但由于内联数据结构的差异,很难integrate.etl是很困难的。现在大部分的数据分析系统采用关系模型。尽管Hadoop与模型不相关,但通常使用的工具是根据关系模型设计的。

解uff1a

使用一个范例来设计一个数据库,即一个引用而不是内联,或者当我们使用内联时,我们给每个内联对象都提供一个全局唯一的键,确保它可以直接与关系模型建立映射关系,从而提高数据模型的灵活性:





blog_id
内容
评论{ }
......




{ {id= 1 内容= NoSQL的反模式是一个很好的文章},{id = 2 }
......





这样的设计可以使用内联的好处并将其映射到关系模型,可以确定的是需要手动维护comment_id确保其全球唯一性。



反模式四:在线计算

症状:存在运行时间长的查询,由于聚合计算不能解决索引问题,随着数据量的增加,它逐渐成为性能瓶颈。

不好的地方:

在联机业务中,如果查询大于4S,用户体验会急剧下降,主要关键字和索引的查询可以满足要求,但是聚合操作通常需要扫描整个表或大量数据。随着数据量的增加,查询时间会变长,用户不可容忍的。影响数据库的性能。长查询的缺点是数不胜数。在网上申请,如果长时间的查询时,大部分的资源,包括CPU、IO、连接等,可占领。这导致其他很好的查询,而且性能也下降,和沉重的无法使用该数据库。长期的查询可以被称为DB的杀手。

解决方案:首先,这是一个权衡,这种聚合操作是没有必要的,必须实时完成。如果不需要实时完成,离线操作可以采取。夜深人静,跑很长的查询和缓存为第二天的结果。如果你有在真正的时间做它,你可以创建一个新的领域,以提高操作,总在实时运行时的结果,而是一个漫长的查询时,查询的执行。如果逻辑比较复杂,如果大量增加操作所带来的压力,数据库系统,实时数据处理框架如风暴可以使用。总之,长查询应谨慎使用。

反模式五:使用内联映射对象的键作为ID

症状:文档数据库支持内联映射类型。map的键用作数据库的主键。





blog_id
内容
评论{ }
......




{1= NoSQL的反模式是一个很好的文章,2=是的} }
......



此反模式是容易犯因为地图数据结构中使用的编程语言。但对于数据库模型,这是一个反模式。

不好的地方:

不都是通过数据库查询(> < =),关系数据库,虽然数据结构可以灵活的查询是有层次的。例如,comment.id,comment.content.that是说,在它的地图类型的关键,可以理解为一个属性名称,而不是作为一个ID,因此,这是一次用,断开数据库控制不能使用各种查询功能,无法查询的索引,文件数据可以由名字索引。例如,comment.id.such数据结构并没有一个固定的列名称,所以索引不能成立。

解决方案:使用数组+ map来解决它:





blog_id
内容
评论{ }
......




{ {id= 1 内容= NoSQL的反模式是一个很好的文章},{id = 2 }
......



在这种方式中,你可以使用comment.id作为索引,你可以使用数据库的查询功能,简单有效。在地图类型的关键是属性名称和值的属性值。这种用法是文档数据库的数据模型的意图,它提供的各种功能可以使用。否则,它不能用。



反模式六:不合理ID

症状:ID使用字符串或更复杂的数据结构,或者全部使用数据库提供的自生成ID:





id(id系统是自生成的)
blog_id
内容
......





......



不好的地方:

我是混沌的。如果你使用自动生成的ID由数据库提供的,也有一个blog_id类似的表中的主键的意义,这是非常糟糕的,而且很容易造成逻辑混乱。由于文档数据库不支持重命名ID,人们习惯于关系数据库实践可以创造自己的逻辑ID字段。这是没有必要的。该指数是巨大的性能low.id是数据库的一个重要组成部分。ID的长度将决定指数的大小(包括主键索引),这直接影响数据库的性能如果指数小于内存,性能会很好,但是一旦指数超过了内存和大TA交流时,性能会急剧下降。长期占用8个字节,和一个20字符UTF8字符串需要大约60字节。相差10倍可以考虑。

解决方案:尝试使用有意义的字段来做id,不要在其他字段中重复它。不要使用复杂的数据类型来做ID,只使用系统提供的int、长或主键类型来做ID.。

文献数据库的逆向模式综述

反模式太多了。这里列出了所有上面的反模式。这个列表基于文档数据库模型。





身份证件
反模式名称
问题



有一个关系表,它描述多对多
{ 00

症状:文档数据库存储在纯关系表中。

坏:{数据完整性破坏,索引太多}

解决方案:添加列表字段

{ }。

编号:01

症状:关系模型不能区分一对多和多对。

缺点:附加索引

解决方法:合理安排场地位置

} }



到处引用客户端连接
{ {

编号:10

症状:查询时需要大量手动连接操作。

坏东西:{手动连接,多个查询,琐碎的事务处理}

解决方案:适当使用内联数据结构。

} }



为将来使用无止境的麻烦
{ {

编号:20

症状:经常查询某些内联字段,丢弃其他字段

坏:{没有ID约束,索引泛滥,性能浪费}

解决方法:代替内联使用引用,并允许数据被重复

{ }。

编号:21

症状:列表、地图类型的内联字段在扩展,没有限制。

坏:{失败,拖动性能

解决方案:设置最大数量或使用引用。

{ }。

编号:22

症状:DBA希望单独维护一个内联字段,但不能这样做。

坏:{管理权限很难,很难裁表,很难备份}

解决方案:在设计数据库模型时需要考虑的维护操作

{ }。

编号:23

症状:应用程序可以对数据库运行的很好。但是,当新的应用程序连接,它会很麻烦。Inline Dingsi的应用

坏:{新的应用程序很难访问,集成很难,ETL困难}

解决方案:使用范例设计数据库,即引用而不是内联。它与关系模型之间有直接映射关系。

} }



在线计算
{ {

编号:30

症状:存在运行时间长的查询,逐渐成为性能瓶颈。

坏:{影响用户体验,影响数据库性能}

解决方案:取消不必要的聚合操作。运行时,实时聚合结果。使用第三方实时或非实时工具,如Hadoop、暴风。

} }



将内联映射对象的键用作id。
{ {

编号:40

症状:文档数据库支持内联映射类型。map的键用作数据库的主键。

坏:{都可以通过数据库()查询,而不是通过索引查询}

解决方案:使用数组+ map来解决它。

} }



不合理的ID
{ {

编号:50

症状:ID带有字符串或更复杂的数据结构,或者全部使用数据库提供的自生成ID。

坏:{ ID混乱,大索引}

解决方案:尝试使用某个字段来做ID。不要使用复杂的数据类型来做ID.

} }





本文试图总结反模式的重要文献数据库,我知道。现在关于NoSQL数据模型设计模式的探讨才刚刚开始,它会逐渐成为未来的一个系统。为柱的数据库和核心价值的反模式,笔者将与你分享它的时候有足够的积累。