数据库相关
数据库安装
不同的数据库在不同系统中安装部署方式可能会不同,这里简单做下记录。
Redis Install
- official docs: https://redis.io/docs/data-types/
- official download: http://download.redis.io/releases/
- os: CentOS 8.2
- redis version: 7.0.6
1. 下载文件
cd / && mkdir sources && cd sources
wget http://download.redis.io/releases/redis-7.0.6.tar.gz && tar -zxvf redis-7.0.6.tar.gz
cd redis-7.0.6
make && make PREFIX=/usr/local/redis install
cp redis.conf /usr/local/redis/bin/
vi /usr/local/redis/redis.conf
检查redis安装:
/usr/local/redis/bin/redis-server -v
启动redis:
/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
后台运行redis正常关闭
./redis-cli shutdown
2. 修改 redis.conf 允许后台运行(如果是supervisor管理则不需要完成后面几步,直接通过supervisor配置)
daemonize yes
3.添加redis 服务
vi /usr/lib/systemd/system/redis.service
[Unit]
Description=Redis
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/redis/bin/redis-server /usr/local/redis/redis.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
4.刷新服务
systemctl daemon-reload
5.开启、停止、查看状态、重启、设置开机启动
systemctl start redis
systemctl status redis
systemctl stop redis
systemctl restart redis
systemctl enable redis
6. make install 直接安装的,可以在redis 解压目录 make uninstall 卸载,如果指定目录安装的,先停止服务,再删除目录即可!
设置redis-cli的提示:
To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
第三方python库: pip3 install redis -i https://pypi.tuna.tsinghua.edu.cn/simple
supervisor自启动
[program:redis7]
command=/usr/local/redis/bin/redis-server /usr/local/redis/bin/redis.conf
autostart=true
autorestart=true
startsecs=5
startretries=500
差异问题
面试中涉及的一些数据库问题。
MongoDB是B树还是B+树
通过查阅资料,可以从 MongoDB 的官网和 WiredTiger 官网找到答案。 MongoDB 官网关于存储引擎(Storage Engine)的描述写道:从 MongoDB 3.2 版本开始,其使用了 WiredTiger 作为其默认的存储引擎。 而从 WiredTiger 官网文档,可以知道:WiredTiger 使用的是 B+ 树作为其存储结构。
结论: MongoDB < 3.2,用的B树; MongoDB >= 3.2,使用B+树。
重点:分清楚B树和B+树的区别;知道在合适的时候,选择合适的数据结构。
B 树(B-tree,不是B减树)与 B+ 树,其比较大的特点是: B 树对于特定记录的查询,其时间复杂度更低。 B+ 树对于范围查询则更加方便,另外 B+ 树相对于 B 树来说更加扁平。
注意:B 树不是二叉树,而是一种自平衡树数据结构。B 树是二叉搜索树的一般化,因为 B 树的节点可以有两个以上的子节点。与其他自平衡二进制搜索树不同,B 树非常适合读取和写入相对较大的数据块(如光盘)的存储系统。
MongoDB为什么不使用平衡二叉树?
(因为MongoDB需要使用B树能加载大数据量的特性)
平衡二叉树的查找效率是非常高的,并可以通过降低树的深度来提高查找的效率。但是当数据量非常大,树的存储的元素数量是有限的,这样会导致二叉查找树结构由于树的深度过大而造成磁盘 I/O 读写过于频繁,进而导致查询效率低下。
MySQL为什么使用B+树?
MySQL 跟 B+ 树没有直接的关系,真正与 B+ 树有关系的是 MySQL 的默认存储引擎 InnoDB,MySQL 中存储引擎的主要作用是负责数据的存储和提取,除了 InnoDB 之外,MySQL 中也支持 MyISAM 作为表的底层存储引擎。
因为 B+ 树只有叶节点会存储数据,将树中的每一个叶节点通过指针连接起来就能实现顺序遍历,而遍历数据在关系型数据库中非常常见,它经常需要处理各个表之间的关系并通过范围查询一些数据,所以这么选择是完全没有问题的。
ref: 为什么 MySQL 使用 B+ 树
Mysql
简单记录各中数据库常用crud命令。
默认端口:3306
查询是否锁表
mysql> show processlist;
+-----------+----------+--------------------+------------+---------+-------+-------+------------------+
| Id | User | Host | db | Command | Time | State | Info |
+-----------+----------+--------------------+------------+---------+-------+-------+------------------+
| 725067379 | mytestdb | 10.10.XX.15:35790 | test_event | Sleep | 21286 | | NULL |
| 725362450 | mytestdb | 10.10.XX.15:39726 | test_event | Sleep | 13862 | | NULL |
| 725816007 | mytestdb | 10.10.XX.222:49839 | test_event | Query | 0 | NULL | show processlist |
| 725822632 | mytestdb | 10.10.XX.15:58585 | test_event | Sleep | 2 | | NULL |
| 725822668 | mytestdb | 10.10.XX.15:58660 | test_event | Sleep | 0 | | NULL |
| 725822669 | mytestdb | 10.10.XX.15:58661 | test_event | Sleep | 0 | | NULL |
| 725822671 | mytestdb | 10.10.XX.15:58666 | test_event | Sleep | 0 | | NULL |
| 725822674 | mytestdb | 10.10.XX.15:58673 | test_event | Sleep | 0 | | NULL |
| 725822675 | mytestdb | 10.10.XX.15:58677 | test_event | Sleep | 0 | | NULL |
+-----------+----------+--------------------+------------+---------+-------+-------+------------------+
9 rows in set (0.00 sec)
查询表中数据总数
-- Innod数据量过大这样查询速度很慢,需要给表加索引
mysql> select count(*) from dev_company_tax;
+----------+
| count(*) |
+----------+
| 12542793 |
+----------+
1 row in set (4.12 sec)
查询某张表的索引
mysql> show index from test_company_tax;
+-----------------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| dev_company_tax | 0 | PRIMARY | 1 | id | A | 12787231 | NULL | NULL | | BTREE | | |
| dev_company_tax | 1 | tax_number | 1 | tax_number | A | 12787231 | NULL | NULL | | BTREE | | |
| dev_company_tax | 1 | isshow | 1 | isshow | A | 20 | NULL | NULL | | BTREE | | |
| dev_company_tax | 1 | is_img_ok | 1 | is_img_ok | A | 20 | NULL | NULL | | BTREE | | |
| dev_company_tax | 1 | is_img_ok_2 | 1 | is_img_ok | A | 20 | NULL | NULL | | BTREE | | |
| dev_company_tax | 1 | is_img_qichacha | 1 | is_img_qichacha | A | 20 | NULL | NULL | | BTREE | | |
| dev_company_tax | 1 | is_img_qichacha_2 | 1 | is_img_qichacha | A | 20 | NULL | NULL | | BTREE | | |
+-----------------+------------+-------------------+--------------+-----------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
7 rows in set (0.34 sec)
extend:
通过MySQL命令查看
show index from tbname;
MySQL通过SQL语句查看表的索引:
1、查看数据库所有索引
SELECT * FROM mysql.`innodb_index_stats` a WHERE a.`database_name` = '数据库名';
2、查看某一表索引
SELECT * FROM mysql.`innodb_index_stats` a WHERE a.`database_name` = '数据库名' and a.table_name like '%表名%';
- 导出指定数据库和其中的表信息
mysqldump -u root -p blog_service > blog_service.sql
- 导入 xxx.sql 到数据库中
mysql -u blog_service < blog_service.sql
当然,也可以用Navicat等图形化工具导入xxx.sql文件。但要注意Navicat导入数据库前要先创建一个同名空数据库,然后再运行sql文件。
Redis
默认端口:6379
能系统安装就不要自己手动装了。
1. Ubuntu安装redis
apt安装
sudo apt-get install redis-server
手动安装 (不推荐)
(详见此文)[https://jingyan.baidu.com/article/00a07f38173cea82d028dc24.html]
下载:wget http://download.redis.io/releases/redis-3.0.6.tar.gz
解压:tar -zxvf redis-3.0.6.tar.gz
编译:cd redis-3.0.6 && make MALLOC=libc
安装:sudo make install
2. Redis常用命令 (on Ubuntu)
一般来说,会在redis安装目录下面,配置一个redis.conf的文件来定制化启动redis
检查Redis是否挂了
ps -ef | grep redis
test@xxx:/data/$ ps -ef | grep redis
ubuntu 6673 1 0 8月19 ? 01:59:52 redis-server *:6379
1.Redis server 6379挂了时,启动reids (带启动文件)
进入redis安装目录
执行下面命令的其中1条:
sudo redis-server redis.conf
sudo ./redis-server ./redis.conf
2.Redis server 没挂时,重启redis
sudo service redis-server restart
sudo /etc/init.d/redis-server restart
or
sudo systemctl restart redis-server (apt或yum安装的redis)
[sudo] password for ubuntu:
Stopping redis-server: redis-server.
Starting redis-server: redis-server.
如果是用apt-get或者yum install安装的redis,可以直接通过下面的命令停止/启动/重启redis.
/etc/init.d/redis-server stop
/etc/init.d/redis-server start
/etc/init.d/redis-server restart
3.Redis问题解决
1. overcommit_memory
2. THP (Transparent Huge Pages)
3. TCP backlog
1. overcommit_memory
错误日志:
ResponseError: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
很多人都是建议“config set stop-writes-on-bgsave-error no”。这样做其实是不好的,这仅仅是让程序忽略了这个异常,使得程序能够继续往下运行,但实际上数据还是会存储到硬盘失败。
当操作系统收到内存分配请求时,它会依据overcommit_memory 设定的条件,考虑接受或者拒绝这个请求
0 — 默认设置 内核使用启发式算法,来估算可用的内存量,直接拒绝不合理的请求
1 — 内核不考虑内存是否够用,直接同意请求,在这种设置下,潜在的内存过载风险增加了,但有利于内存密集型任务
2 — 如果程序请求的内存分配大于等于 交换分区和物理内存的总和 * overcommit_ratio / 100 则拒绝这个请求 默认是 交换分区和物理内存总和的50%
默认设置是0,只要内存请求超过物理内存的剩余量,请求就会被拒绝。 设置1,不管实际物理内存使用量,直接同意请求。设置1是一种比较粗放式的对内存请求的管理方式,我认为更为优雅的方式是使用2,并且将overcommit_ratio 的值设为60 ~ 80
解决方法:
细致式:
echo "vm.overcommit_memory=2" >> /etc/sysctl.conf
echo "vm.overcommit_ratio=70" >> /etc/sysctl.conf
sysctl -p
sysctl -p 不用重启使配置生效
粗旷式:
echo "vm.overcommit_memory=1" >> /etc/sysctl.conf
2. THP(Transparent Huge Pages)透明大页
透明大页,默认是always,启用是为了可以管理更多的内存地址空间。可以使用never关闭,之后会使用系统软件的算法管理内存映射。
通常linux会将透明大页开启,在fork被调用后,redis产生的延迟被用来持久化到磁盘。内存大页会引起一下问题:
1.fork被调用,共享内存大页的两个进程被创建
2.在一个系统比较活跃的实例里,部分循环时间运行需要几千个内存页,期间引起的copy-on-write 会消耗几乎所有的内存
3.这个将导致更大的延迟和使用更多的内存
因此,redis官方建议需要确保禁掉内存大页:
echo never > /sys/kernel/mm/transparent_hugepage/enabled
错误日志:
WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
使用的是透明大页,可能导致redis延迟和内存使用问题。
查看是否使用透明大页
➜ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never]
Linux默认设置使[always]
解决使用的是透明大页,可能导致redis延迟和内存使用问题。
解决方法:
临时解决方法
sudo su # 先切换到root用户
echo never > /sys/kernel/mm/transparent_hugepage/enabled # root用户执行此命令
➜ cat /sys/kernel/mm/transparent_hugepage/enabled
always madvise [never] # 选择的使never说明设置成功,默认是[always]
永久解决方法:
将其写入/etc/rc.local文件中:
iftest -f /sys/kernel/mm/redhat_transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/redhat_transparent_hugepage/enabled
fi
3. TCP backlog
常见报错:
# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
# Server started, Redis version 3.2.6
对于linux 而言backlog 是指已经完成了3次握手,且等待 accept 的连接 如果被没有被accept, 连接会一直在队列中排队,队列的最大长度为 backlog 由此可知, 在client非常多且创建和关闭连接非常频繁的场景下,这个参数会非常有用。
解决方法:
echo "net.core.somaxconn = 511" >> /etc/sysctl.conf
sysctl -p
Redis主从复制
MongoDB
默认端口:27017
常用命令:
1.检查mongod启动没有
pgrep mongo -l
2.mongodb的后台启动,配置文件(mongodb.conf)自己写(能不用root就别用root),日志注意不要写到/var下
mongod --config /etc/mongodb.conf
3.直接命令行带参数不用配置文件启动
mongod --dbpath /data/mongodb/db/ --logpath /data/mongodb/log/mongod.log --fork --auth --bind_ip 127.0.0.1(要允许访问就设置为0.0.0.0)
MongoDB CRUD
show dbs;
show tables;
show collections;
# del collections
use test
db.one.drop()
# insert single data
db.one.save({"name":"Alan","age":42}) # 5+
db.one.insert({"name":"Bob","age":38}) # 4.4
# insert many
db.one.insertMany([{"name":"Claire","age":33},{"name":"David","age":29}, {"name":"Eric","age":26}])
# loop insert
for (var i=1; i<=100; i++) db.two.insert({num:i, name:'a'});
# find data
db.two.find()
# name no use add quotation mark
db.one.find({name:"Eric"})
# update data
db.one.update({name:"Alan"},{$set:{name:"Alice"}})
# delete data
db.one.remove({name:"Eric"})
db.two.remove()
# condition operation
# condition find
db.one.find({age:{$gt: 30}})
db.one.find({age:{$lt: 30}})
db.one.find({$and:[{"name": "Bob"},{"age":38}]})
db.one.find({$or:[{"name": "Bob"},{"age":33}]})
MongoDB statistics
# sort 1 升序, -1 降序
db.one.find().sort({age:1})
db.one.find({age:{$gt: 30}}).sort({age:1})
# collection count
db.one.count()
db.one.find({age:{$gt: 30}}).count()
# specific field sum
db.three.insertMany([{name:"zhao",class:1,score:89},{name:"qian",class:1,score:92},{name:"sun",class:2,score:94},{name:"li",class:2,score:88}])
# 分组求和 按class字段分组,sum_score为求和之后的字段,对score字段进行分组求和。
db.three.aggregate([{'$group':{_id:'$class','sum_score':{'$sum':'$score'}}}])
[ { _id: 2, sum_score: 182 }, { _id: 1, sum_score: 181 } ]
aggregate() mongodb的聚合函数
# 分组求平均值
db.three.aggregate([{'$group':{_id:'$class','avg_score':{'$avg':'$score'}}}])
# 分组最大值
db.three.aggregate([{'$group':{_id:'$class','max_score':{'$max':'$score'}}}])
# 分组最小值
db.three.aggregate([{'$group':{_id:'$class','min_score':{'$min':'$score'}}}])
MongoDB Index
索引的作用:提高检索速度
MongoDB批量插入测试数据
for (var i=1; i <= 10000; i++) db.four.insert({num:i,name:'a'})
db.four.find().limit(10)
索引原理
- B+树索引
- 为什么索引能提高MongoDB的查询速度?
MongoDB中的索引能够提高查询速度的原因主要有以下几点:
1.减少扫描数据的数量:MongoDB的查询操作需要扫描集合中的数据,如果没有索引,就需要扫描整个集合。而有了索引之后,MongoDB可以直接定位到符合查询条件的数据,从而减少扫描的数据量,提高查询效率。
2.减少磁盘IO操作:MongoDB中的索引通常都是存储在内存中的,因此查询索引所需的IO操作比扫描整个集合所需的IO操作要少得多,这也是索引能够提高查询速度的一个重要原因。
3.提高查询效率:MongoDB中的索引能够直接定位到符合查询条件的数据,从而避免了在集合中进行全文本搜索的开销,提高了查询效率。
4.支持排序和聚合操作:MongoDB中的索引能够支持排序和聚合操作,这些操作通常需要对数据进行多次扫描,而有了索引之后,MongoDB可以直接使用索引来完成这些操作,从而提高查询效率。
需要注意的是,索引的设计和使用需要根据实际业务需求和数据特点进行优化和调整,不当的索引设计和使用可能会降低查询效率,甚至造成性能问题。
因此,在使用索引时,需要仔细考虑索引的类型、字段选择、索引覆盖等因素,并进行适当的优化和调整。
增加升序索引
1.添加单键索引
db.four.createIndex({"num":1})
# 设置降序索引,则是用-1
2.添加组合索引
db.four.createIndex({"num":1,"name":1})
db.four.getIndexes()
3.添加多值索引
db.five.insert({"name":"martin",tag: ["a","b","c"]})
db.five.insert({"name":"jim",tag: ["c","d","e","f"]})
db.five.createIndex({"tag":1})
db.five.find({tag:"b"})
db.five.find({tag:"c"})
4.添加全文索引
注意:一个集合最多创建一个全文索引。
给集合five的name字段添加全文索引。
db.five.createIndex({"name": "text"})
db.five.getIndexes()
5.添加哈希索引
不支持范围查询,不支持多键hash。
db.five.createIndex({"name": "hashed"})
db.five.getIndexes()
6.添加地理位置索引
db.six.insertMany([{loc:[9,9]},{loc:[11,11]},{loc:[100,100]}])
db.six.createIndex({"loc": "2d"})
db.six.getIndexes()
# loc查询,落在矩阵中的点会被查到
db.six.find({loc:{$geoWithin: {$box:[[10,10],[12,12]]}}})
查询索引
db.four.getIndexes()
删除索引
注意这里删除的是索引名字
db.four.dropIndex("num_1")
MongoDB索引类型
- 单键索引(默认B+树结构):添加单字段索引
- 组合索引(默认B+树结构)
- 多值索引(默认B+树结构):也称“数组索引”
- 全文索引(默认B+树结构):一个集合最多创建一个全文索引
- 哈希索引(非默认,需手动创建):使用哈希函数将索引键映射到一个固定大小的哈希值,并将哈希值存储在索引中。
- 地理位置索引
关于哈希索引的补充:
Hash索引适用于等值查询,即查询一个特定的键值是否存在。
与B树索引不同,Hash索引没有排序的概念,因此在范围查询和排序操作中,Hash索引的效率会比较低。
但是,对于等值查询,Hash索引通常比B树索引更快速和高效,因为它使用哈希函数可以直接定位到哈希值对应的存储位置,而不需要进行多次查找。
MongoDB查询计划
执行语句后面加.explain()
for (var i=1; i<=10000; i++) db.four.insert({num:i, name:'a'});
db.four.find({num:99}).explain()
建一张不加索引的表做对比
for (var i=1; i<=10000; i++) db.seven.insert({num:i, name:'a'});
db.seven.getIndexes()
db.seven.find({num:99}).explain(true)
explain()的三种显示方法
Method 1: 查询计划的详细信息
db.four.find({num:99}).explain()
or
db.four.find({num:99}).explain("queryPlanner")
Method 2: 详细分布查询计划
db.four.find({num:99}).explain("executionStats")
Method 3: 所有的执行计划(一般建议的方式)
db.four.find({num:99}).explain("allPlansExecution")
or
db.four.find({num:99}).explain(true)
结果分析
executionStats -> nReturned 返回结果的行数
executionStats -> executionTimeMillis 返回结果的时间,单位毫秒
executionStats -> totalKeysExamined 返回结果扫描了多少索引项
executionStats -> totalDocsExamined 返回结果扫描了多少文档
nReturned/totalDocsExamined 如果比值大,说明执行计划性能差
executionStats -> executionStages -> stage COLLSCAN表示全结合扫描,FETCH表示索引扫描
MongoDB慢查询
开启和关闭慢查询
# 查看慢查询是否开启
db.getProfilingLevel()
如果返回是0,表示没有开启慢查询。1表示已开启慢查询。
# 开启慢查询
db.setProfilingLevel(1,100)
表示MongoDB开启慢查询,并将执行时间超过100ms的语句归为慢查询,并记录在系统中。
# 关闭慢查询
db.setProfilingLevel(0)
如何找到慢查询
1.插入测试数据
for (var i=1; i<=300000; i++) db.eight.insert({num:i, name:'a'})
db.eight.find().count()
2.开启慢查询
# 不加索引正常查询大约87ms
db.setProfilingLevel(1,50)
3.进行查询语句,触发慢查询
db.seven.find({"num":9999})
4.查询系统慢查询
# 按时间查看最新1条慢查询,并格式化输出查询结果
db.system.profile.find().sort({ts:-1}).limit(1).pretty()
慢查询分析
# 重点参数说明
command # 表示执行的命令
keysExamined # 索引扫描数
docsExamined # 文档扫描数
execStats -> stage -> COLLSCAN # 表示全集合扫描
client # 显示客户信息,定位慢查询的来源
{
"op" : "query",
"ns" : "test.eight",
"command" : {
"find" : "eight",
"filter" : {
"num" : 9999
},
"lsid" : {
"id" : UUID("01513c75-839c-4d6a-8275-94f0779e732c")
},
"$db" : "test"
},
"keysExamined" : 0,
"docsExamined" : 300000,
"cursorExhausted" : true,
"numYield" : 300,
"nreturned" : 1,
"queryHash" : "35269713",
"planCacheKey" : "35269713",
"locks" : {
"FeatureCompatibilityVersion" : {
"acquireCount" : {
"r" : NumberLong(302)
}
},
"ReplicationStateTransition" : {
"acquireCount" : {
"w" : NumberLong(302)
}
},
"Global" : {
"acquireCount" : {
"r" : NumberLong(302)
}
},
"Database" : {
"acquireCount" : {
"r" : NumberLong(301)
}
},
"Collection" : {
"acquireCount" : {
"r" : NumberLong(301)
}
},
"Mutex" : {
"acquireCount" : {
"r" : NumberLong(1)
}
}
},
"flowControl" : {
},
"storage" : {
},
"responseLength" : 149,
"protocol" : "op_msg",
"millis" : 87,
"planSummary" : "COLLSCAN",
"execStats" : {
"stage" : "COLLSCAN",
"filter" : {
"num" : {
"$eq" : 9999
}
},
"nReturned" : 1,
"executionTimeMillisEstimate" : 7,
"works" : 300002,
"advanced" : 1,
"needTime" : 300000,
"needYield" : 0,
"saveState" : 300,
"restoreState" : 300,
"isEOF" : 1,
"direction" : "forward",
"docsExamined" : 300000
},
"ts" : ISODate("2023-06-29T17:36:55.333Z"),
"client" : "127.0.0.1",
"appName" : "MongoDB Shell",
"allUsers" : [
{
"user" : "root",
"db" : "admin"
}
],
"user" : "root@admin"
}
MongoDB设置用户权限
mongo
>use admin
db.createUser({
user:"root",
pwd:"xxxxxx",
roles: [{role:"root", db:"admin"}]
})
提示Successfully added user表示添加成功
MongoDB用密码登录
mongo -uroot -p
MongoDB用户管理
添加管理员用户并赋权
db.createUser({
user:"root",
pwd:"xxxxxx",
roles: [{role:"root", db:"admin"}]
})
添加普通用户并赋权
db.createUser({
user:"guest",
pwd:"xxxxxx",
roles: [{role:"readWrite", db:"guest"}]
})
查看用户
> use guest
> show users
> use admin
> db.system.users.find()
删除用户
> use guest
> db.dropUser("guest")
MongoDB不进入mongo shell设置用户权限的方式
在不进入Mongo Shell的情况下进行用户创建操作,可以使用Mongo Shell的--eval
选项来执行一段指令,从而实现在脚本中创建用户的目的。
以下是一个示例,展示如何在脚本中使用--eval
选项创建用户:
mongo admin --eval 'db.createUser({ user: "<username>", pwd: "<password>", roles: [{ role: "<role_name>", db: "<database_name>" }, { role: "<role_name>", db: "<database_name>" }, ... ] })'
请将
您可以将上述命令添加到您的安全启动脚本中,以便在启动时自动创建用户。请确保在脚本中使用适当的安全措施,例如保护脚本的访问权限和存储密码的安全性。
除了使用--eval选项,还可以考虑使用MongoDB的其他管理工具(如mongo-shell-scripts、Node.js与MongoDB驱动程序、Python与PyMongo等)来编写更复杂的脚本,以实现更灵活的用户管理操作。
e.g.
mongo admin --eval ''
MongoDB备份和恢复数据操作
未开用户认证
备份:
mongodump --db=<dump_db_name> --out=<path_to_backup_file>
恢复:
如果备份数据文件是压缩文件(例如.tar.gz或.zip文件),则可以在命令中添加--gzip或--archive选项来指定文件格式,例如:
mongorestore --db=mydb --gzip /data/backup/mydb.bson.gz
已开用户认证
备份
mongodump -u<db_user> -p<db_pwd> --authenticationDatabase=<auth_db> --db=<dump_db_name> --out=<path_to_backup_file>
e.g.
mongodump -uroot -p123456 --authenticationDatabase=admin --db=atest --out=/tmp/mongobk/
会在/tmp/mongobk/下导出一个名为 atest 的目录,里面是指定DB的所有数据。
恢复数据,指定数据库
mongorestore -u<db_user> -p<db_pwd> --authenticationDatabase=<auth_db> --db=<dump_db_name> <path_to_backup_file>
e.g.
mongorestore -uroot -p123456 --authenticationDatabase=admin --db=btest ./atest/
场景,将数据库root_node_v3中task集合,导出后再导入root_node_v2中的task集合。
# 导出单个collection的命令
mongodump -uroot -123456 --authenticationDatabase=admin --db=root_node_v3 --collection=task --out=/tmp/mongobk/task_col.json
2023-08-25T23:31:26.893+0800 writing root_node_v3.task to /tmp/mongobk/task_col.json/root_node_v3/task.bson
2023-08-25T23:31:26.894+0800 done dumping root_node_v3.task (9 documents)
# 导入单个collection的命令
MongoDB 4.4
mongodb shell指定导出某个collection的数据库
mongorestore -u<db_user> -p<db_pwd> --authenticationDatabase=<auth_db> --db=<dump_db_name> --collection=<collection_name> <path_to_backup_file>
e.g.
mongorestore -uroot -p123456 --authenticationDatabase=admin --db=root_node_v2 --collection=task /tmp/mongobk/task_col.json/root_node_v3/task.bson
MongoBD删除数据库
use xxx_test
db.dropDatabase()
MongoDB常用内置角色
root 超级管理员
readWrite 对某个分系统库的读写权限
read 对某个分系统库的只读权限
readWriteAnyDatabase 对所有数据库的读写权限
readAnyDatabase 对所有数据库的只读权限
MongoDB官方可视化工具Compass
官方可下载,支持各种平台。
Compass本身自带MongoDB分析工具,可辅助分析。
另外商业软件Navicat也已支持MongoDB。
要使用mongodb命令需要安装下在 MongoDB Shell
windows mongosh登录需要直接填连接字符串(可从Compass上复制),如:
mongodb://root:yourpassword@192.168.3.10:27017/?authMechanism=DEFAULT&authSource=admin
PostgreSQL
默认端口:5432
其他问题
关系型数据库数据搜索缺点
1.无法打分(无法对搜索出来的结果进行排序)
2.无分布式
3.无法解析搜索请求
4.效率低(上亿)
5.分词