# Day18 MongoDB之旅(上)

# MongoDB 概述

  • 以JSON为数据模型的文档数据库
  • 与MySQL对比
MySQL           MongoDB
database        database
table           collection
row             document
index           index
join            embedded document
foreign key     reference
partition       shard
  • 文档
文档是MongoDB的核心概念,文档就是键值对的一个有序集{'code':0, 'msg':'hello world'},类似于Python中的有序字典

- 文档中的键/值对是有序的
- 文档中的值不仅可以是在双引号里面的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)
- MongoDB区分类型和大小写
- MongoDB的文档不能有重复的键

- .和$有特别的意义,只有在特定环境下才能使用
- 以下划线"_"开头的键是保留的(不是严格要求的)
  • 集合
集合就是一组文档,相当于一张表
  • 数据库
多个文档组成集合,多个集合可以组成数据库

# 保留数据库名
- admin: 从身份认证的角度讲,这是"root"数据库,如果将一个用户添加到admin数据库,这个用户将自动获得所有数据库的权限。再者,一些特定的服务器端命令也只能从admin数据库运行,如列出所有数据库或关闭服务器
- local: 这个数据库永远都不可以复制,且一台服务器上的所有本地集合都可以存储在这个数据库中
- config: MongoDB用于分片设置时,分片信息会存储在config数据库中
  • 把数据库名添加到集合名前,得到集合的完全限定名,即命名空间

# 安装与启动

  • 下载
# 下载
https://www.mongodb.com/try/download/community

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.23.tgz
mv mongodb-linux-x86_64-rhel70-4.2.23 /usr/local/mongodb

# 配置到环境变量中
vim /etc/profile
export PATH=/usr/local/mongodb/bin:$PATH
source /etc/profile

# 错误提示
mongod: error while loading shared libraries: libcrypto.so.10: cannot open shared object file: No such file or directory
# 原因 缺失libcrypto.so.10 未安装
# 解决方法
rpm -qa  | grep libcrypto.so
rpm -qa  | grep libcrypt
yum install compat-openssl10
  • 环境准备
# 创建登录和组
useradd mongod
passwd mongod

# 规划目录
mkdir -p /mongodb/conf
mkdir -p /mongodb/log
mkdir -p /mongodb/data

chown -R mongod:mongod /mongodb
  • 启动数据库并初始化
# 切换用户
su - mongod

# 启动
mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork

# 登录
mongo

# 关闭
mongod --dbpath=/mongodb/data --logpath=/mongodb/log/mongodb.log --port=27017 --logappend --fork --shutdown
  • 配置文件
vim /mongodb/conf/mongdb.conf

# 普通文件形式
dbpath=c
logpath=/mongodb/log/mongodb.log
port=27017
logappend=true
fork=true


# yaml形式
systemLog:
    destination: file
    path: "/mongodb/log/mongodb.log"
    logAppend: true
storage:
    journal:
        enabled: true
    dbPath: "/mongodb/data"
processManagement:
    fork: true
net:
    port: 27017
    bindIp: 127.0.0.1

# 启动
mongod -f /mongodb/conf/mongdb.conf

# 关闭
mongod -f /mongodb/conf/mongdb.conf --shutdown

# 基本数据类型

  • 加强版 JSON 数据类型
1null:用于表示空或不存在的字段
d={'x':null}

2、布尔型:truefalse
d={'x':true,'y':false}

3、数值
d={'x':3,'y':3.1415926}

4、字符串
d={'x':'linda'}

5、日期
d={'x':new Date()}
d.x.getHours()

6、正则表达式
d={'pattern':/^linda.*?nb$/i}

正则写在//内,后面的i代表:
i 忽略大小写
m 多行匹配模式
x 忽略非转义的空白字符
s 单行匹配模式

7、数组
d={'x':[1,'linda', true]}

8、内嵌文档
user={'name':'linda','addr':{'country':'China','city':'BJ'}}
user.addr.country

9、对象id:是一个12字节的ID,是文档的唯一标识,不可变
d={'x':ObjectId()}
  • _id和ObjectId
- MongoDB中存储的文档必须有一个"_id"键,这个键的值可以是任意类型,默认是个ObjectId对象
- 不同集合"_id"的值可以重复,但同一集合内"_id"的值必须唯一
- ObjectId是"_id"的默认类型,初衷就是用作分布式数据库,12字节唯一标识

ObjectId采用12字节的存储空间,是一个由24个十六进制数字组成的字符串
0|1|2|3|   4|5|6|   7|8     9|10|11    
时间戳      机器      PID     计数器

-9个字节确保了同一秒钟不同机器不同进程产生的ObjectId是唯一的
- 最后3个字节是一个自动增加的计数器,确保相同进程的同一秒产生的ObjectId也是不一样的

# 复制集 RS(Replica Set)

复制集作用在于实现服务高可用,依赖两方面

  • 数据写入时将数据迅速复制到另外一个独立节点上,通过库表中中的 oplog 来实现
  • 在主节点发生故障时,自动选出新的替代节点,通过互相的心跳实现
  • 可实现读写分离,常见主 从 从,从库只能开启读,不能写

# 配置过程

  • 基本配置
同一台服务器,多个端口号实例演示
1. 端口号:28017、28018、28019、28020

2. 多目录:
su - mongod
mkdir -p /mongodb/28017/conf /mongodb/28017/data /mongodb/28017/log
mkdir -p /mongodb/28018/conf /mongodb/28018/data /mongodb/28018/log
mkdir -p /mongodb/28019/conf /mongodb/28019/data /mongodb/28019/log
mkdir -p /mongodb/28020/conf /mongodb/28020/data /mongodb/28020/log

3. 配置文件内容:
cat > /mongodb/28017/conf/mongod.conf <<EOF
systemLog:
    destination: file
    path: "/mongodb/28017/log/mongodb.log"
    logAppend: true
storage:
    journal:
        enabled: true
    dbPath: "/mongodb/28017/data"
    wiredTiger:
        engineConfig:
            cacheSizeGB: 0.15
            directoryForIndexes: true
        collectionConfig:
            blockCompressor: zlib
        indexConfig:
            prefixCompression: true
processManagement:
    fork: true
net:
    port: 28017
    bindIp: 0.0.0.0
replication:
    oplogSizeMB: 2048
    replSetName: 'my_repl'
EOF

cp /mongodb/28017/conf/mongod.conf /mongodb/28018/conf
cp /mongodb/28017/conf/mongod.conf /mongodb/28019/conf
cp /mongodb/28017/conf/mongod.conf /mongodb/28020/conf

sed 's#28017#28018#g' /mongodb/28018/conf/mongod.conf -i
sed 's#28017#28019#g' /mongodb/28019/conf/mongod.conf -i
sed 's#28017#28020#g' /mongodb/28020/conf/mongod.conf -i

4. 启动多个实例
mongod -f /mongodb/28017/conf/mongod.conf
mongod -f /mongodb/28018/conf/mongod.conf
mongod -f /mongodb/28019/conf/mongod.conf
mongod -f /mongodb/28020/conf/mongod.conf

5. 测试关闭
mongod -f /mongodb/28017/conf/mongod.conf --shutdown
mongod -f /mongodb/28018/conf/mongod.conf --shutdown
mongod -f /mongodb/28019/conf/mongod.conf --shutdown
mongod -f /mongodb/28020/conf/mongod.conf --shutdown
  • 配置复制集
mongo --port 28017

config = {
    _id: 'repl', members: [
        {_id: 0, host: '127.0.0.1:28017'},
        {_id: 1, host: '127.0.0.1:28018'},
        {_id: 2, host: '127.0.0.1:28019'}]
}
rs.initiate(config)
  • 测试复制集
# 主库读写
repl:PRIMARY> use db1
repl:PRIMARY> db.t1.insert({'key': 'value'

# 从库默认没有开启读,且不能写
repl:SECONDARY>rs.secondaryOk()
repl:SECONDARY>use db1
repl:SECONDARY>show collection
repl:SECONDARY>db.t1.find()
{ "_id" : ObjectId("6358c5cf77acf5d0a00e9b52"), "key" : "value" }

# 查看状态
rs.status()
rs.isMaster()
rs.config()
  • 管理复制集
rs.add('127.0.0.1:18020')       -- 新增节点
rs.addArb('127.0.0.1:18020')    -- 新增仲裁节点
rs.remove('127.0.0.1:18020')    -- 删除节点
上次更新: 10/31/2022, 5:19:53 PM