MongoDB底层数据结构常用命令
Posted _less is more
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MongoDB底层数据结构常用命令相关的知识,希望对你有一定的参考价值。
1、数据结构
下图来自于StackOverflow
如上图,左边是B树(中间那是一杠,不是减号),右边是B+树
- B树【MongoDB】
每个节点都有key和value,因此没有重复的key和value。但查找时会有更多【缓存未命中】的情况,因为当前遍历到的key即便不是我们要的,他对应的数据指针也会一起进入内存,导致内存中的key数量会比B+树少。
最快访问到一个想要节点的可以是O(1),因此对于频繁访问的数据放到离根节点越近的地方,访问会越快,而B+树没有这个优势,因为B+中的内部节点只有key没有对应的data指针。
由于所有数据分布于整颗树上的每一个节点,因此如果要遍历一遍,需要遍历树中所有层,这样的遍历需要回溯,消耗更多栈空间。
- B+树【mysql】
内部节点(非叶节点)只有key没有value,因此在内存中,一个内存页可以存储更多的key,因此在查找时比较key大小的时候,【缓存未命中】的情况会更少,因为cache中会有更多的key。
叶节点包含所有的完整的key和相对应的value,因此内部节点的key算是重复,但这样的重复有利于快速查找。
叶节点指针互相连接,因此遍历一遍只需要线性地依次查找所有的叶节点即可。对于MySQL需要访问一个区间数据的情况能提供更高效的查找。
本质区别
- B树每个节点都有key和对应数据的指针;B+树只有叶节点才有key和对应数据的指针,内部节点只有用于查找的key
- B树的叶节点之间没有指针;B+树叶节点之间有指针
2、BSON和JSON
JSON格式很常见
"_id": 1,
"name": "first" : "John", "last" : "Backus" ,
"contribs": [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ]
而BSON仅仅只是二进制版本的JSON,因此不具有可读性,像这样
\\x31\\x00\\x00\\x00
\\x04BSON\\x00
\\x26\\x00\\x00\\x00
\\x02\\x30\\x00\\x08\\x00\\x00\\x00awesome\\x00
\\x01\\x31\\x00\\x33\\x33\\x33\\x33\\x33\\x33\\x14\\x40
\\x10\\x32\\x00\\xc2\\x07\\x00\\x00
\\x00
\\x00
3、数据库操作
查看
show dbs
进入数据库,如果test数据库不存在,则自动创建
use test
删除数据库,在test数据库中,使用如下命令,则会删除当前正在使用的数据库
db.dropDatabase()
4、collection操作,相当于表
查看所有collections
show collections
创建collection
db.createCollection("mycollection")
删除collection
db.mycollection.drop()
向collection中插入,如果名为class的collection不存在则自动创建
db.class.insert('name':'ee547')
查看表中内容
> db.class.find()
"_id" : ObjectId("632a16e412de6627982e581b"), "name" : "ee547"
5、实战1
创建一个collection
db.createCollection('my_data')
插入数据
db.my_data.insert([
title: "MongoDB Overview",
description: "MongoDB is no SQL database",
by: "tutorials point",
tags: ["mongodb", "database", "NoSQL"],
likes: 100
,
title: "NoSQL Database",
description: "NoSQL database doesn't have tables",
by: "tutorials point",
tags: ["mongodb", "database", "NoSQL"],
likes: 20
])
查看刚插入的数据
> db.my_data.find()
"_id" : ObjectId("6333b19a3dc8391635c169b0"), "title" : "MongoDB Overview", "description" : "MongoDB is no SQL database", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100
"_id" : ObjectId("6333b19a3dc8391635c169b1"), "title" : "NoSQL Database", "description" : "NoSQL database doesn't have tables", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 20
用更好观察类似JSON格式的方式输出
> db.my_data.find().pretty()
"_id" : ObjectId("6333b19a3dc8391635c169b0"),
"title" : "MongoDB Overview",
"description" : "MongoDB is no SQL database",
"by" : "tutorials point",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 100
"_id" : ObjectId("6333b19a3dc8391635c169b1"),
"title" : "NoSQL Database",
"description" : "NoSQL database doesn't have tables",
"by" : "tutorials point",
"tags" : [
"mongodb",
"database",
"NoSQL"
],
"likes" : 20
用条件过滤查找,这里是and,也可以是or,nor等等;这里表示查找title和by字段为特定字符串的document(即关系数据库中的row)
> db.my_data.find( $and: [ title: 'MongoDB Overview', by: 'tutorials point'])
"_id" : ObjectId("6333b19a3dc8391635c169b0"), "title" : "MongoDB Overview", "description" : "MongoDB is no SQL database", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100
更新title,可以看到将title为MongoDB Overview的document的title改为了New name
> db.my_data.find()
"_id" : ObjectId("6333b19a3dc8391635c169b0"), "title" : "MongoDB Overview", "description" : "MongoDB is no SQL database", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100
"_id" : ObjectId("6333b19a3dc8391635c169b1"), "title" : "NoSQL Database", "description" : "NoSQL database doesn't have tables", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 20
> db.my_data.update(title:'MongoDB Overview',$set:title:'New name')
WriteResult( "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 )
> db.my_data.find()
"_id" : ObjectId("6333b19a3dc8391635c169b0"), "title" : "New name", "description" : "MongoDB is no SQL database", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100
"_id" : ObjectId("6333b19a3dc8391635c169b1"), "title" : "NoSQL Database", "description" : "NoSQL database doesn't have tables", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 20
同时更新多个document,找到by字段为tutorials point的documents,然后把他们的by字段改为tutorials point222,第三个参数中的multi:true即表示允许修改多个,不加这个则只会更新一个
> db.my_data.find()
"_id" : ObjectId("6333b19a3dc8391635c169b0"), "title" : "New name", "description" : "MongoDB is no SQL database", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100
"_id" : ObjectId("6333b19a3dc8391635c169b1"), "title" : "NoSQL Database", "description" : "NoSQL database doesn't have tables", "by" : "tutorials point", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 20
> db.my_data.update(
... by:'tutorials point',
... $set:by:'tutorials point222',
... multi:true
... )
WriteResult( "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 )
> db.my_data.find()
"_id" : ObjectId("6333b19a3dc8391635c169b0"), "title" : "New name", "description" : "MongoDB is no SQL database", "by" : "tutorials point222", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 100
"_id" : ObjectId("6333b19a3dc8391635c169b1"), "title" : "NoSQL Database", "description" : "NoSQL database doesn't have tables", "by" : "tutorials point222", "tags" : [ "mongodb", "database", "NoSQL" ], "likes" : 20
6、实战2
创建collection
db.createCollection("empDetails")
使用insertOne命令插入一个document并查看
> db.empDetails.insertOne(
... First_Name: "Radhika",
... Last_Name: "Sharma",
... Date_Of_Birth:"1995-09-26",
... e_mail: "radhika_sharma.123@gmail.com",
... phone:"9848022338"
... )
"acknowledged" : true,
"insertedId" : ObjectId("6333b4013dc8391635c169b2")
> db.empDetails.find()
"_id" : ObjectId("6333b4013dc8391635c169b2"), "First_Name" : "Radhika", "Last_Name" : "Sharma", "Date_Of_Birth" : "1995-09-26", "e_mail" : "radhika_sharma.123@gmail.com", "phone" : "9848022338"
使用insertMany同时插入多个,当然按照前面直接用insert命令插入多个也可以
> db.empDetails.insertMany([
...
... First_Name: "Doe",
... Last_Name: "Joe",
... Date_Of_Birth:"1995-10-24",
... e_mail: "doe_joe.123@gmail.com",
... phone:"1234567890"
... ,
...
... First_Name: "Rachel",
... Last_Name: "Christopher",
... Date_Of_Birth:"1990-02-16",
... e_mail: "Rachel_Christopher.123@gmail.com",
... phone:"9000054321"
... ,
...
... First_Name: "Fathima",
... Last_Name: "Sheik",
... Date_Of_Birth:"1990-02-16",
... e_mail: "Fathima_Sheik.123@gmail.com",
... phone:"9000054321"
...
... ])
"acknowledged" : true,
"insertedIds" : [
ObjectId("6333b44d3dc8391635c169b3"),
ObjectId("6333b44d3dc8391635c169b4"),
ObjectId("6333b44d3dc8391635c169b5")
]
> db.empDetails.find()
"_id" : ObjectId("6333b4013dc8391635c169b2"), "First_Name" : "Radhika", "Last_Name" : "Sharma", "Date_Of_Birth" : "1995-09-26", "e_mail" : "radhika_sharma.123@gmail.com", "phone" : "9848022338"
"_id" : ObjectId("6333b44d3dc8391635c169b3"), "First_Name" : "Doe", "Last_Name" : "Joe", "Date_Of_Birth" : "1995-10-24", "e_mail" : "doe_joe.123@gmail.com", "phone" : "1234567890"
"_id" : ObjectId("6333b44d3dc8391635c169b4"), "First_Name" : "Rachel", "Last_Name" : "Christopher", "Date_Of_Birth" : "1990-02-16", "e_mail" : "Rachel_Christopher.123@gmail.com", "phone" : "9000054321"
"_id" : ObjectId("6333b44d3dc8391635c169b5"), "First_Name" : "Fathima", "Last_Name" : "Sheik", "Date_Of_Birth" : "1990-02-16", "e_mail" : "Fathima_Sheik.123@gmail.com", "phone" : "9000054321"
查看一个document,具体查看的是哪个则根据排序而定,通常是输出最开始插入的那一个,因为第一个插入的_id最小
> db.empDetails.findOne()
"_id" : ObjectId("6333b4013dc8391635c169b2"),
"First_Name" : "Radhika",
"Last_Name" : "Sharma",
"Date_Of_Birth" : "1995-09-26",
"e_mail" : "radhika_sharma.123@gmail.com",
"phone" : "9848022338"
赋值,并输出其_id
> employee = db.empDetails.findOne()
"_id" : ObjectId("6333b4013dc8391635c169b2"),
"First_Name" : "Radhika",
"Last_Name" : "Sharma",
"Date_Of_Birth" : "1995-09-26",
"e_mail" : "radhika_sharma.123@gmail.com",
"phone" : "9848022338"
> employee._id
ObjectId("6333b4013dc8391635c169b2")
7、_id
MongoDB中一个很重要的东西就是_id,由数据库管理系统自动生成,其类型是ObjectId,长度为12-byte,ObjectId("6333b401 3dc8391635 c169b2")
中的一个数字是十六进制,用4个bits来表示,而一个byte是8个bits,因此12-byte则可以表示24个十六进制的数
前4个byte,代表这个ObjectId相对于Unix epoch的创建时间,用秒表示;Unix epoch 是UTC世界标准时间1970年一月一日0时0分0秒
中间5个byte,是随机生成的,这串数在此机器和进程上是唯一的
后3个byte,是递增的数,初始化为一个随机生成的数,而非从0开始计
8、实战:排序
直接插入多个document,collection被自动创建,根据borough字段按字母排序,1表示递增排序
> db.restaurants.insertMany( [
... "_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan",
... "_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens",
... "_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn",
... "_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan",
... "_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn",
... ] );
"acknowledged" : true, "insertedIds" : [ 1, 2, 3, 4, 5 ]
> db.restaurants.find().sort( "borough": 1 )
"_id" : 3, "name" : "Empire State Pub", "borough" : "Brooklyn"
"_id" : 5, "name" : "Jane's Deli", "borough" : "Brooklyn"
"_id" : 1, "name" : "Central Park Cafe", "borough" : "Manhattan"
"_id" : 4, "name" : "Stan's Pizzaria", "borough" : "Manhattan"
"_id" : 2, "name" : "Rock A Feller Bar and Grill", "borough" : "Queens"
按递减排序
> db.orders.MongoDB shell操作