龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 数据库类 > nosql开发 >

NoSQL反模式 - 文档数据库篇(2)

时间:2014-08-26 03:30来源:网络整理 作者:网络 点击:
分享到:
id user_id blog_id 0 0 0 1 0 1 这样的表就算在关系模型中也是不妥的,因为这个ID非常的多余,可以用联合主键来解决。但是在文档数据库中,由于必须强制单主

id user_id blog_id
0 0 0
1 0 1
这样的表就算在关系模型中也是不妥的,因为这个ID非常的多余,可以用联合主键来解决。但是在文档数据库中,由于必须强制单主键,不得不采取这样的设计。

坏处:

破坏数据完备性。由于ID是主键,在数据模型上没有约束来保证不出现重复的user_id,blog_id对。一旦数据出现重复,更新删除都是问题。索引过多。由于是关系表,必须在user_id和blog_id上面分别建一个索引。影响性能。

解决方案:使用文档数据库典型的处理多对多的办法。不是建立一张关系表,而是在其中一个文档(如User)中,加入一个List字段。

 

user_id user_name blog_id[] ……
0 Jake 0,1 ……
1 Rose 1,2 ……

问题二:没有区分"一对多关系"和“多对一关系”症状:关系模型不区分“一对多”和“多对一”,对于文档数据库来讲,关系模型只有“多对一”。就像这张Comment表:

comment_id user_id content ……
0 0 “NoSQL反模式是好文章” ……
1 0 “是啊” ……

如果整个模型都是这样的“多对一”关系就需要反思了。

坏处:

额外索引。如果客户端已知user_id,需要获得User信息和Comment信息,需要执行两次查询。其中一次查询需要使用索引。并且要在客户端自己Join。这样可能有潜在性能问题。

解决方案:问题的核心在于是已知user_id查询两张表,还是已知comment_id查询两张表。如果是已知comment_id这样的设计就是合理的,但是如果是已知user_id来查询,把关系放在user表里的设计更合理一些。

user_id user_name comment_id[] ……
0 Jake 0,1 ……
1 Rose 1,2 ……

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

正确使用的场合:

关系型模型是非常成功的数据模型,合理的沿用是非常好的。但是由于文档数据库的特点,需要适当的调整,这样得出的数据模型,尽管性能不是最优,但是有最好的灵活性。并且也有利于和关系数据库转换。

反模式二:处处引用客户端Join

症状:数据库设计中充满了xx_id的字端,在查询的时候需要大量的手动Join操作。就涉及到了这个反模式。正如上面提到的博客的关系模型,如果已知blog_id查询comments,需要至少执行3次查询,并且手动Join。

坏处:

手动Join,麻烦且易出错。文档数据库不支持Join且没有外键保证。因此需要在客户端Join,这样的操作对于软件开发来讲是比较繁琐的。由于没有外键保证,因此不能保证取得的ID在数据库里面是有数据的。在处理的时候需要不断判断,容易出错。多次查询。如果引用过多,查询的时候需要多次查询才能查到足够的数据。本来文档数据库是很快的,但是由于多次查询,给数据库增加了压力,获取全部数据的时间也会增加。事务处理繁琐。文档数据库一般不支持一般意义上事务,只支持行锁。如果文档数据库有给多个连接。在插入的时候,事务的处理就是噩梦。在文档数据库中使用事务,需要使用行锁,在进行大量的处理。太过繁琐,感兴趣的读者可以搜一下。

精彩图集

赞助商链接