在MOGNODB 的文档设计和存储中,存在两个部分 1 嵌套 2 数组,所以如果想设计好一个MONGODB 在理解业务,读写比例,查询方式后,就需要介入到更深层次的理解嵌套的查询方式,嵌套多层后的性能问题, 数组其实比嵌套带来更多的问题,所以今天我们的从数组开始。
MONGODB 中的数组是属于同类型数据的元素集合,每个数组中的元素代表这个数组中同样属性的不同值,其实我们可以理解为,在一个JSON 中,有行和行列集合的存在,本身JSON可以通过数组的方式,在一个平面里面表达一个列的集合。
下面我们操作插入多条记录,其中包含了一个以 score 为主的分数的数组,其中包含每个数据库的分数
db.databases.insertMany([ { system_name: "oracle", b_time: 1975, score: [90,70,55] }, { system_name: "mysql", b_time: 1990, score: [100,60,55]}, { system_name: "postgresql", b_time: 1978, score: [100,80,65] }, { system_name: "sql server", b_time: 1980, score: [60,45,25] }, { system_name: "mongodb", b_time: 2001, score: [100,90,55]} ]);
实际上我们也可以将上方的记录设计成 db.databases1.insertMany([ { system_name: "oracle", b_time: 1975, score1: 90, score2:80,score3:75 }, { system_name: "mysql", b_time: 1990, score1: 100, score2:70,score3:55}, { system_name: "postgresql", b_time: 1978, score1: 100, score2:80,score3:75 }, { system_name: "sql server", b_time: 1980, score1: 60, score2:55,score3:45 }, { system_name: "mongodb", b_time: 2001, score1: 100, score2:7,score3:65} ]);
上方有的两个设计都已经将数据库的打分记录了,一种是以数组的方式,一种是以键值对的方式进行记录。
那么我们看看这样的设计不同对于后续的使用有什么不同
1 进行查询
我们要查询整体每种数据库的打分的个数,也就是我们看看每个数据库有多少的打分。相当于对每个ducument 中的数据进行元素的计算,这样就可以得到每个数据库的被打分的个数, 而第二组设计则无法进行分析的和统计。 db.databases.aggregate([{$project: { count: { $size:"$score" }}}]) ,
这里的project 是控制聚合后显示的列,这里我们通过 $size 匹配所有的score中数组的元素,并进行count ,然后进行聚合操作,并通过project进行投射的工作,最终显示出下图的内容,每行score的元素个数。
而上面不通过数组进行的document的设计方式,则很难进行相关的统计分析操作。
我们对数组建立索引,db.databases.createIndex({score:1})
现在我们要找出每个数据库中打分高于90的数据
db.databases.find({score:{$gt:90}},{system_name:1,"_id":0}
而没有使用数组的设计的方式,则需要对每一个score1 score2 score3 分别进行查询,并将结果合并后去重后,才能得到相应的结果。
同时为了保证查询的速度需要对score1, score2, score3 分别建立索引并,这样索引占用的空间也比上一种方式要大。
可以比对两种设计模式中,使用数组的方式建立的多键值索引对比分开的索引容量缩减了60%。
数组在一部分应用设计中适合进行数据查询,而另外一点就是数组的缺点,就是对数组中的数据进行更新,尤其是高频次,大量的数据更新和数据的添加。
下面就是针对ORACLE 添加在数组中添加一个数据元素。
db.databases.update({system_name:"oracle"},{$push:{"score":30}})
对数据进行更新,将刚才的加入的数组元素进行修改db.databases.update({system_name:"oracle"},{$set:{"score.4":50}})
另外对于数组的另外一个功能,就是将一些设计中的行转换在MONGODB的数组方式,类似于行转列的方式设计。
数组在MONGODB 中存在的意义很大,在很多设计中都可以通过数组的使用降低查询的复杂度和降低建立索引的SIZE。