mongoDB学习

一、NoSQL介绍

1.NoSQL简介

NoSQL(Not Only SQL),非关系型数据库的总称

对NoSQL最普遍的解释是”非关联型的”,强调Key-Value Stores和文档数据库的优点,而不是单纯的反对RDBMS。 
NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。

2.为什么使用NoSQL

关系型数据对于字段要求严格,而非关系型数据库则不那么严格,对于大量不同的数据存储,NoSQL比较方便

二、mongoDB简介

Mongodb由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。是专为可扩展性,高性能和高可用性而设计的数据库, 是非关系型数据库中功能最丰富,最像关系型数据库的,它支持的数据结构非常散,是类似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。

MongoDB的(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业,各个行业以及各类应用程序的开源数据库。作为一个适用于敏捷开发的数据库,MongoDB的的数据模式可以随着应用程序的发展而灵活地更新。

json格式  {key:value,key:value}
bjson格式  {key:value,key:value}

{id:1}  json格式,数据 1 只用了一个字节,bjson格式,数据 1 用了最少4字节

1.mongoDB结构

mysql mongoDB
集合
字段 key 键
行数据 key:value 文档

1)数据库数据结构(student库,user表)

id name age gender
1 zhangyu 18
2 xiaomaoge 19

2)mongoDB数据(student库,user集合)

1) {id:1,name:zhangyu,age:18,gender:"男"}
2){id:2,name:xiaomage,age:19,gender:"男"}

2.MongoDB特点

1.高性能:
    Mongodb 提供高性能的数据持久性,索引支持更快的查询

2.丰富的语言查询:
    Mongodb 支持丰富的查询语言来支持读写操作(CRUD)以及数据汇总

3.高可用性: 
    Mongodb 的复制工具,成为副本集,提供自动故障转移和数据冗余

4.水平可扩展性:
    Mongodb 提供了可扩展性,作为其核心功能的一部分,分片是将数据分在一组计算机上。

5.支持多种存储引擎: 
    WiredTiger存储引擎和、 MMAPv1存储引擎和 InMemory 存储引擎
    3.0以上版本            3.0以下版本
    新的引擎压缩比特别大,原来100个G,可能升级之后所有数据都在,只占用10个G

6.强大的索引支持:
    地理位置索引可用于构建 各种 O2O 应用、文本索引解决搜索的需求、TTL索引解决历史数据自动过期的需求

3.MongoDB应用场景

1.游戏场景:
    用来存储玩家用户信息,装备,积分,排行榜
2.物流场景:
    通过地理位置索引,可以显示快递位置或者订单信息
3.社交场景:
    存储用户信息,存朋友圈,空间;
    通过地理位置索引,查询附近的人
4.视频直播:
    存储用户信息,刷礼物
5.购物场景:
    有些产品有特定的参数,衣服有胸围,裤子有腰围,数据库存储需要多个表
    mongoDB只需要一个表就可以解决

三、mongoDB安装部署

1.安装依赖

[root@redis03 ~]# yum install -y openssl libcurl

2.上传或下载包

#下载包地址:
https://www.mongodb.com/download-center/community

#上传包:
[root@redis03 ~]# rz mongodb-linux-x86_64-3.6.13.tgz

3.解压

[root@redis03 ~]# tar xf mongodb-linux-x86_64-3.6.13.tgz -C /usr/local/

#创建软连接
[root@redis03 ~]# ln -s /usr/local/mongodb-linux-x86_64-3.6.13 /usr/local/mongodb

4.配置

#创建mongodb的目录
[root@redis03 ~]# mkdir /server/mongodb/27017/{conf,logs,pid,data} -p

#配置
[root@redis03 ~]# vim /server/mongodb/27017/conf/mongo.conf
systemLog:
  destination: file
  logAppend: true
  path: /server/mongodb/27017/logs/mongodb.log

storage:
  journal:
    enabled: true
  dbPath: /server/mongodb/27017/data
  directoryPerDB: true
  wiredTiger:
     engineConfig:
        cacheSizeGB: 1
        directoryForIndexes: true
     collectionConfig:
        blockCompressor: zlib
     indexConfig:
        prefixCompression: true

processManagement:
  fork: true
  pidFilePath: /server/mongodb/27017/pid/mongod.pid

net:
  port: 27017
  bindIp: 127.0.0.1,10.0.0.93

#配置详解
#日志部分 
systemLog:
  #日志以文件的形式保存
  destination: file
  #重启的时候,新的日志直接保存在文件后面,不新生成文件
  logAppend: true
  #指定日志文件
  path: /server/mongodb/27017/logs/mongodb.log
#数据部分
storage:
  #数据回滚
  journal:
    enabled: true
  #数据目录
  dbPath: /server/mongodb/27017/data
  #搜索引擎兼容,不是InMemory存储引擎
  directoryPerDB: true
  #指定存储引擎
  wiredTiger:
       #存储引擎设置
     engineConfig:
         #数据先写到缓存,缓存的大小
        cacheSizeGB: 1
        #设置开启一个库就生成一个目录
        directoryForIndexes: true
     #开启压缩
     collectionConfig:
        blockCompressor: zlib
     #索引压缩
     indexConfig:
        prefixCompression: true
#守护进程
processManagement:
  fork: true
  #指定pid文件
  pidFilePath: /server/mongodb/27017/pid/mongod.pid
#指定端口和监听地址
net:
  port: 27017
  bindIp: 127.0.0.1,10.0.0.93

5.启动

[root@redis03 ~]# /usr/local/mongodb/bin/mongod -f /server/mongodb/27017/conf/mongo.conf

#验证
[root@redis03 ~]# ps -ef | grep mongo
root      18023      1  1 13:06 ?        00:00:00 /usr/local/mongodb/bin/mongod -f /server/mongodb/27017/conf/mongo.conf

6.配置环境变量

[root@redis03 ~]# vim /etc/profile.d/mongo.sh
export PATH="/usr/local/mongodb/bin:$PATH"

[root@redis03 ~]# source /etc/profile

7.连接mongoDB

[root@redis03 ~]# mongo
MongoDB shell version v3.6.13
connecting to: mongodb://127.0.0.1:27017/?gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("24bd1fb1-5646-48f8-a871-d321901d8a4f") }
MongoDB server version: 3.6.13
Server has startup warnings: 
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] 
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] 
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] 
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] 
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] 
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 7837 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files.
2020-05-27T13:06:21.666+0800 I CONTROL  [initandlisten] 
>

四、优化MongoDB解决报错

1.警告一

#数据库的访问控制未启用
WARNING: Access control is not enabled for the database.

#解决方式:
开启访问控制

2.警告二

#警告:您正在以root用户的身份运行这个进程,这是不推荐的。
WARNING: You are running this process as the root user, which is not recommended.

#解决方式:
1.关闭mongodb
[root@redis03 ~]# mongod -f /server/mongodb/27017/conf/mongo.conf --shutdown

2.创建用户
[root@redis03 ~]# useradd mongo

3.授权数据目录
[root@redis03 ~]# chown -R mongo.mongo /server/mongodb/

4.切换用户启动
[root@redis03 ~]# su - mongo
Last login: Wed May 27 13:22:53 CST 2020 on pts/0
[mongo@redis03 ~]$ mongod -f /server/mongodb/27017/conf/mongo.conf
about to fork child process, waiting until server is ready for connections.
forked process: 19077
child process started successfully, parent exiting

3.警告三、四

#警告:/sys/kernel/mm/transparent_hugepage/enabled是'always',我们建议将其设置为'never'
WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
#警告:/sys/kernel/mm/transparent_hugepage/defrag is 'always',我们建议将其设置为'never'
WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.

#解决方法:
[root@redis03 ~]# echo never > /sys/kernel/mm/transparent_hugepage/enabled
[root@redis03 ~]# echo never > /sys/kernel/mm/transparent_hugepage/defrag

4.警告五

#警告:软限制太低。设置为7837个进程,65535个文件。进程数至少为32767.5:0.5乘以文件数。
WARNING: soft rlimits too low. rlimits set to 4096 processes, 65535 files. Number of processes should be at least 32767.5 : 0.5 times number of files.

#解决方式:
1.先修改root用户的进程限制数
[root@redis03 ~]# vim /etc/profile
ulimit -u 65535
[root@redis03 ~]# source /etc/profile

2.再修改普通用户的进程限制数
[root@redis03 ~]# vim /etc/security/limits.d/20-nproc.conf 
*          soft    nproc     65535
root       soft    nproc     unlimited

3.切换用户再次查看进程限制
[root@redis03 ~]# su - mongo
Last login: Wed May 27 13:37:51 CST 2020 on pts/0
[mongo@redis03 ~]$ ulimit -a
max user processes              (-u) 65535

五、数据操作

1.基本操作

#查看数据库
> show databases
admin   0.000GB            #系统库,系统管理
config  0.000GB            #配置信息
local   0.000GB            #本地库,存储日志

show databases/show dbs        #查看数据库
use admin                   #切换数据库(mongodb中,没有库也可以进行切换,添加数据后才能看到库)
show tables/show collections    #查看库里面的集合
db                          #查看当前所在库

2.插入数据

#插入一条数据
> db.table.insert({"id":1,"name":"qiudao","age":38,"gender":"m"})
WriteResult({ "nInserted" : 1 })

#插入单条数据
> db.table.insertOne({"id":2,"name":"banzhang","age":18,"gender":"m"})
{
    "acknowledged" : true,
    "insertedId" : ObjectId("5ece084c3230a0c32e8509b6")
}

#插入多条数据
> db.table.insertMany([{"name":"gcc","age":10},{"name":"zzy","age":9},{"name":"hxh","age":11}])
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5ece09a33230a0c32e8509b7"),
        ObjectId("5ece09a33230a0c32e8509b8"),
        ObjectId("5ece09a33230a0c32e8509b9")
    ]
}

#添加数据时,字段可以不加双引号,值如果不是数字一定要加双引号
> db.table.insertMany([{name:"gcc",age:10},{name:"zzy",age:9},{name:"hxh",age:11}])
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5ece09f03230a0c32e8509ba"),
        ObjectId("5ece09f03230a0c32e8509bb"),
        ObjectId("5ece09f03230a0c32e8509bc")
    ]
}

#添加多条数据,数据多条件
> db.table.insertMany([{name:"qiudao",age:38,figure:{height:120,weight:160}},{name:"zzy",age:88,figure:{height:110,weight:900}}])
{
    "acknowledged" : true,
    "insertedIds" : [
        ObjectId("5ece0b283230a0c32e8509bd"),
        ObjectId("5ece0b283230a0c32e8509be")
    ]
}

3.查看数据

#查看所有数据
> db.table.find()
{ "_id" : ObjectId("5ece07ec3230a0c32e8509b5"), "id" : 1, "name" : "qiudao", "age" : 38, "gender" : "m" }
{ "_id" : ObjectId("5ece084c3230a0c32e8509b6"), "id" : 2, "name" : "banzhang", "age" : 18, "gender" : "m" }
{ "_id" : ObjectId("5ece09a33230a0c32e8509b7"), "name" : "gcc", "age" : 10 }
{ "_id" : ObjectId("5ece09a33230a0c32e8509b8"), "name" : "zzy", "age" : 9 }
{ "_id" : ObjectId("5ece09a33230a0c32e8509b9"), "name" : "hxh", "age" : 11 }
{ "_id" : ObjectId("5ece09f03230a0c32e8509ba"), "name" : "gcc", "age" : 10 }
{ "_id" : ObjectId("5ece09f03230a0c32e8509bb"), "name" : "zzy", "age" : 9 }
{ "_id" : ObjectId("5ece09f03230a0c32e8509bc"), "name" : "hxh", "age" : 11 }
{ "_id" : ObjectId("5ece0b283230a0c32e8509bd"), "name" : "qiudao", "age" : 38, "figure" : { "height" : 120, "weight" : 160 } }
{ "_id" : ObjectId("5ece0b283230a0c32e8509be"), "name" : "zzy", "age" : 88, "figure" : { "height" : 110, "weight" : 900 } }
{ "_id" : ObjectId("5ece0b7f3230a0c32e8509bf"), "id" : 3, "name" : "zengdao", "age" : 18, "gender" : "m", "size" : "little" }

#查看一条数据(只能查看到第一条)
> db.table.findOne()
{
    "_id" : ObjectId("5ece07ec3230a0c32e8509b5"),
    "id" : 1,
    "name" : "qiudao",
    "age" : 38,
    "gender" : "m"
}

#按条件查询
> db.table.find({age:10})
{ "_id" : ObjectId("5ece09a33230a0c32e8509b7"), "name" : "gcc", "age" : 10 }
{ "_id" : ObjectId("5ece09f03230a0c32e8509ba"), "name" : "gcc", "age" : 10 }

> db.table.findOne({name:"gcc"})
{ "_id" : ObjectId("5ece09a33230a0c32e8509b7"), "name" : "gcc", "age" : 10 }

> db.table.find({age:18})
{ "_id" : ObjectId("5ece084c3230a0c32e8509b6"), "id" : 2, "name" : "banzhang", "age" : 18, "gender" : "m" }
{ "_id" : ObjectId("5ece0b7f3230a0c32e8509bf"), "id" : 3, "name" : "zengdao", "age" : 18, "gender" : "m", "size" : "little" }

#按多条件查询(且)
> db.table.find({age:18,name:"banzhang"})
{ "_id" : ObjectId("5ece084c3230a0c32e8509b6"), "id" : 2, "name" : "banzhang", "age" : 18, "gender" : "m" }

#按多条件查询(或)
> db.table.find({$or:[{age:18},{name:"gcc"}]})
{ "_id" : ObjectId("5ece084c3230a0c32e8509b6"), "id" : 2, "name" : "banzhang", "age" : 18, "gender" : "m" }
{ "_id" : ObjectId("5ece09a33230a0c32e8509b7"), "name" : "gcc", "age" : 10 }
{ "_id" : ObjectId("5ece09f03230a0c32e8509ba"), "name" : "gcc", "age" : 10 }
{ "_id" : ObjectId("5ece0b7f3230a0c32e8509bf"), "id" : 3, "name" : "zengdao", "age" : 18, "gender" : "m", "size" : "little" }

#如果数据条件是集合的
> db.table.find({"figure.height":120})
{ "_id" : ObjectId("5ece0b283230a0c32e8509bd"), "name" : "qiudao", "age" : 38, "figure" : { "height" : 120, "weight" : 160 } }

#查询范围数据
> db.table.find({"figure.height":{$gt:100}})
{ "_id" : ObjectId("5ece0b283230a0c32e8509bd"), "name" : "qiudao", "age" : 38, "figure" : { "height" : 120, "weight" : 160 } }
{ "_id" : ObjectId("5ece0b283230a0c32e8509be"), "name" : "zzy", "age" : 88, "figure" : { "height" : 110, "weight" : 900 } }
#书写格式优化
db.table.find(
  {
    $or:
      [
        {age:18},
        {name:"gcc"}
      ]
  }
)

#查询结构优化
> db.table.find({"figure.height":{$gt:100}}).pretty()
{
    "_id" : ObjectId("5ece0b283230a0c32e8509bd"),
    "name" : "qiudao",
    "age" : 38,
    "figure" : {
        "height" : 120,
        "weight" : 160
    }
}
{
    "_id" : ObjectId("5ece0b283230a0c32e8509be"),
    "name" : "zzy",
    "age" : 88,
    "figure" : {
        "height" : 110,
        "weight" : 900
    }
}

4.修改数据

#修改单条数据
> db.table.updateOne({name:"qiudao"},{$set:{"figure.height":130}})
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

#修改多条数据
> db.table.updateMany({age:18},{$set:{gender:"f"}} )
{ "acknowledged" : true, "matchedCount" : 2, "modifiedCount" : 2 }

#添加字段(当我们修改数据所没有的字段时,就是添加字段)
> db.table.update({name:"zzy",age:250},{$set:{gender:"f"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

#可以根据_id修改数据
> db.table.update({_id:ObjectId("5ece0b7f3230a0c32e8509bf")},{$set:{gender:"m"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Copyright © 高程程 all right reserved,powered by Gitbook修订于: 2021-05-18 21:14:59

results matching ""

    No results matching ""