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指针。

由于所有数据分布于整颗树上的每一个节点,因此如果要遍历一遍,需要遍历树中所有层,这样的遍历需要回溯,消耗更多栈空间。

内部节点(非叶节点)只有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操作

Linux常用命令

python | mongodb 常用命令

数据库-mongodb-常用命令

MongoDB常用命令

MongoDB常用命令