MongoDB 数据库结构
不管我们学习什么数据库,首先都要了解其中的基础概念。在 MongoDB 中基本的概念是文档、集合、数据库,这也是该数据库的基本结构。
MongoDB 分四级存储:
数据库 db
文档集合 collection(相当于 MySQL 的数据表)
文档 document(相当于 MySQL 数据表里的一条数据)
字段
下表清楚地展示了各级关系及描述:
image.png
对于熟悉 MySQL 数据库的同学来说,MongoDB 的数据库结构是可以很容易理解的。
创建数据库
打开实验环境,在终端执行如下命令启动 MongoDB 服务,并进入命令行交互客户端:
$ sudo service mongodb start
$ mongo
我们可以使用 show dbs 命令查看现有数据库:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>
在 MySQL 中,我们使用 CREATE DATABASE xxx 命令创建数据库,使用 CREATE TABLE xxx 创建数据表。在使用数据库或数据表之前,必须要创建它们。
在 MongoDB 中,可以直接插入数据,无需预先创建各种约束。而且 MongoDB 单纯创建数据库的操作其实是不存在的,我们可以使用 use 数据库名 切换到某个数据库,如果该数据库不存在的话,在创建集合时会自动创建此数据库。
MongoDB 默认已经存在三个数据库,现在要在 shiyanlou 数据库中的 test1 集合中存储一条数据:
{ "name": "Kobe", "age": 29, "addr": ["Los", "Tor"] }
具体操作如下:
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> use shiyanlou
switched to db shiyanlou
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
> db.test1.insertOne(
... {name: 'Kobe', age: 39, addr: ['Los', 'Tor']}
... )
{
"acknowledged" : true,
"insertedId" : ObjectId("5e48ccb33e3378fbcbcc7f98")
}
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
shiyanlou 0.000GB
>
如上所示,执行 use shiyanlou 命令后再次查看数据库列表,其中并未新建数据库。
下一个命令 db.test1.insertOne ,其中 db 指的是 shiyanlou 这个数据库,虽然它未被创建。test1 指的是集合的名字,这个名字是可以自定义的,db.test1 就是指 shiyanlou 数据库中的 test1 集合。insertOne 函数用于向集合中添加文档,所谓文档,就是一条数据。顾名思义,insertOne 只能向集合中添加一条数据。
大家对 JSON 数据一定不陌生,MongoDB 中一切数据都是 JSON 的格式,也就是 Key-Value 键值对。insertOne 的参数就是这样的键值对,键值对在 Python 编程语言中对应 dict 类型的数据,在 Java 编程语言中对应 Map 类型的数据。在这些编程语言中,一个键值对对象中不允许出现相同的 Key ,MongoDB 中亦是如此,不过即使有相同的 Key 也不会报错,而是覆盖。
插入数据后,再次执行 show dbs 命令查看数据库列表,发现最后一行就是新增的 shiyanlou 数据库。也就是说使用 use 命令并不能创建数据库,只有插入数据的时候才会创建数据库和集合。
创建集合
数据库中的集合又叫做 “文档集合”,因为它是用来存放文档(也就是一条数据)的。查看当前所使用的数据库中集合的命令为 show collections :
> show collections
test1
>
与创建数据库不同,除了在添加第一条数据的时候顺便创建集合,还可以使用 db.createCollection 函数创建集合,集合的名字作为参数:
> db.createCollection('test2')
{ "ok" : 1 }
> show collections
test1
test2
>
注意在 MongoDB 中变量的命名遵循小驼峰命名法,即多个单词组成的变量,第一个单词全小写,后面的单词首字母大写,例如 createCollection 。
创建集合的函数如下:
db.createCollection(name, options)
其中第 1 个参数为集合名字,第二个参数为 {xxx: xxx} 键值对,用于对集合增加一些限制项:
db.createCollection( <name>,
{
capped: <boolean>,
autoIndexId: <boolean>,
size: <number>,
max: <number>,
storageEngine: <document>,
validator: <document>,
validationLevel: <string>,
validationAction: <string>,
indexOptionDefaults: <document>,
viewOn: <string>, // Added in MongoDB 3.4
pipeline: <pipeline>, // Added in MongoDB 3.4
collation: <document>, // Added in MongoDB 3.4
writeConcern: <document>
}
)
有兴趣的话大家可以到官方文档中查询各项的作用:点此处查看官方文档 。
插入数据
查询文档集合中的数据使用 find 函数:
> db.test1.find()
{ "_id" : ObjectId("5e48d57a3e3378fbcbcc7f9b"), "name" : "Kobe", "age" : 39, "addr" : [ "Los", "Tor" ] }
>
如上所示,查询结果为一条文档,其中的 name 、age 、addr 这些 Key 我们很清楚,就是插入的数据,但是出现了一个特别的字段 _id ,它可以看作是一条数据的唯一身份编号,这是数据库提供的功能,每一条文档都会有这个数据,其数据类型为 ObjectId 。
前面的操作已经向 shiyanlou 数据库的 test1 集合中插入一条数据,使用的是集合的 insertOne 函数。显然应该有对应的插入多条数据的函数 insertMany ,我们来尝试这样操作:
> db.test1.find()
{ "_id" : ObjectId("5e48d57a3e3378fbcbcc7f9b"), "name" : "Kobe", "age" : 39, "addr" : [ "Los", "Tor" ] }
> db.test1.insertMany(
... [
... {name: 'Nash', age: 43, addr: ['Pho', 'Los']},
... {name: 'Jame', age: 33, addr: ['Mia', 'Cle']}
... ]
... )
{
"acknowledged" : true,
"insertedIds" : [
ObjectId("5e48d5b93e3378fbcbcc7f9c"),
ObjectId("5e48d5b93e3378fbcbcc7f9d")
]
}
> db.test1.find()
{ "_id" : ObjectId("5e48d57a3e3378fbcbcc7f9b"), "name" : "Kobe", "age" : 39, "addr" : [ "Los", "Tor" ] }
{ "_id" : ObjectId("5e48d5b93e3378fbcbcc7f9c"), "name" : "Nash", "age" : 43, "addr" : [ "Pho", "Los" ] }
{ "_id" : ObjectId("5e48d5b93e3378fbcbcc7f9d"), "name" : "Jame", "age" : 33, "addr" : [ "Mia", "Cle" ] }
>
使用 insertOne 插入一条数据时,参数为 {xxx} ;使用 insertMany 插入多条数据时,记得要用中括号将多个 {xxx} 括起来。中括号就是列表的符号,大括号就是字典的符号。
操作截图如下:
image.png
在插入数据时,键值对的 Key 通常不需要加引号,就像上面的操作一样。有些时候需要加引号,例如 Key 存在空格时:
> db.test1.insert(
... {'n a m e': 'Wade', age: 22}
... )
WriteResult({ "nInserted" : 1 })
> db.test1.find()
{ "_id" : ObjectId("5e48d57a3e3378fbcbcc7f9b"), "name" : "Kobe", "age" : 39, "addr" : [ "Los", "Tor" ] }
{ "_id" : ObjectId("5e48d5b93e3378fbcbcc7f9c"), "name" : "Nash", "age" : 43, "addr" : [ "Pho", "Los" ] }
{ "_id" : ObjectId("5e48d5b93e3378fbcbcc7f9d"), "name" : "Jame", "age" : 33, "addr" : [ "Mia", "Cle" ] }
{ "_id" : ObjectId("5e48d82c3e3378fbcbcc7f9e"), "n a m e" : "Wade", "age" : 22 }
>
如上所示,这次又使用了一个新函数 insert 来插入数据。这个函数才是最常用的插入数据的函数,它不限数量,可以插入一条数据,也可以插入多条数据。当然啦,插入多条数据时也要用中括号将数据括起来。
删除集合和数据库
删除集合的操作十分简单,就是调用集合的 drop 函数:
> show collections
test1
test2
> db.test1.drop()
true
> show collections
test2
>
删除数据库也是很简单,如果数据库里没有集合,这个数据库自然就被删除了。现在删除 test2 集合:
> show collections
test2
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
shiyanlou 0.000GB
> db.test2.drop()
true
> show collections
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>
当 shiyanlou 数据库中没有集合,那么这个数据库便不再存在了。当然啦,此时的 db 仍指向 shiyanlou 这个不存在的数据库:
> db
shiyanlou
>
如果要直接删除数据库呢?也是可以的,使用 db.dropDatabase() 函数:
> db.createCollection('test1')
{ "ok" : 1 }
> db.createCollection('test2')
{ "ok" : 1 }
> show collections
test1
test2
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
shiyanlou 0.000GB
> db.dropDatabase()
{ "dropped" : "shiyanlou", "ok" : 1 }
> show dbs
admin 0.000GB
config 0.000GB
local 0.000GB
>
网友评论