文章目录
Mongodb简介
mysql mongodb Redis
MongoDB是一个开源、高性能、无模式(模式自由)的文档型数据库
应用场景:
- 支持文本查询
- 不需要支持事务,不存在复杂的多表查询,不支持join操作
- 存储数据可持久化
- 需要TB甚至 PB 级别数据存储
- 需求变化较快,数据模型无法确认,预计使用快速迭代开发形式
- 需要至少2000以上的读写QPS【高性能】
- 能支持快速水平扩展【高扩展】
- 99.999%高可用【高可用】
- 适合于数据价值低的数据存储
小结:mongo的特点 1、模式自由 ---- 不需要提前创建表 直接放数据就可以
2、支持高并发 2000以上
3、搭建集群比较方便
4、支持海量数据存储
MongoDB体系结构
MongoDB 的逻辑结构是一种层次结构。主要由:文档(document)、集合(collection)、数据库(database)这三部分组成的。逻辑结构是面向用户的,用户使用 MongoDB 开发应用程序使用的就是逻辑结构。
- MongoDB 的文档(document),相当于关系数据库中的一行记录。
- 多个文档组成一个集合(collection),相当于关系数据库的表。
- 多个集合(collection),逻辑上组织在一起,就是数据库(database)。
- 一个 MongoDB 实例支持多个数据库(database)。
文档(document)、集合(collection)、数据库(database)的层次结构如下图:
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection|table | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
MongoDB数据类型
数据类型 | 描述 |
---|---|
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Array | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Object ID | 对象 ID。用于创建文档的 ID。 自动生成的一个主键 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Regular expression | 正则表达式类型。用于存储正则表达式。 |
ObjectId
ObjectId 类似唯一主键,可以很快的去生成和排序,包含 12 bytes,含义是:
- 前 4 个字节表示创建 unix 时间戳,格林尼治时间 UTC 时间,比北京时间晚了 8 个小时
- 接下来的 3 个字节是机器标识码
- 紧接的两个字节由进程 id 组成 PID
- 最后三个字节是随机数
MongoDB 中存储的文档必须有一个 _id 键。这个键的值可以是任何类型的,默认是个 ObjectId 对象
MongoDB安装
cd /opt/hmtt/nosql
./close.sh
./start.sh
mongo客户端工具安装
安装后启动,连接MongoDB
MongoDB基本操作
数据库以及表的操作
// 查看数据库
show dbs
// 创建数据库
// use 数据库名称 如果数据库名称存在,那么切换到该数据库,不如不存在,那就新增数据库
use article
use student
use commentdb
// 查看当前所在数据库
db
// 删除数据库
// db.dropDatabase() 删除当前所在的数据库
db.dropDatabase()
// 操作集合
// 查看集合
show tables
// 新增集合
// db.createCollection(集合名)
db.createCollection("student")
// 删除集合
// db.集合名.drop()
db.student.drop()
新增数据
在MongoDB中,存储的文档结构是一种类似于json的结构,称之为bson(全称为:Binary JSON)。
// 新增文档
// db.集合名.insert(文档) json格式的文档
db.comment.insert({"name":"tom","age":18})
db.comment.insert({"_id":2,"name":"jerry","age":19})
// 查看所有文档
// db.集合名.find()
db.comment.find()
查询数据
MongoDB 查询数据的语法格式如下:
db.表名.find([query],[fields])
- query :可选,使用查询操作符指定查询条件
- fields :可选,使用投影操作符指定返回的键。查询时返回文档中所有键值, 只需db.省略该参数即可(默认省略)。
如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:
>db.表名.find().pretty()
pretty() 方法以格式化的方式来显示所有文档。
MongoDB 与 RDBMS Where 语句比较
操作 | 格式 | 范例 | RDBMS中的类似语句 |
---|---|---|---|
等于 | {:} | db.col.find({"userId":"101"}) | where userId= '101' |
小于 | {:{$lt:}} | db.col.find({"thumpUp":{$lt:50}}) | where thumpUp < 50 |
小于或等于 | {:{$lte:}} | db.col.find({"thumpUp":{$lte:50}}) | where thumpUp <= 50 |
大于 | {:{$gt:}} | db.col.find({"thumpUp":{$gt:50}}) | where thumpUp > 50 |
大于或等于 | {:{$gte:}} | db.col.find({"thumpUp":{$gte:50}}) | where thumpUp >= 50 |
不等于 | {:{$ne:}} | db.col.find({"thumpUp":{$ne:50}}) | where thumpUp != 50 |
包含使用$in操作符
查询评论集合中userid字段包含101和102的文档:
db.comment.find({userId:{$in:["101","102"]}})
不包含使用$nin操作符
查询评论集合中userid字段不包含101和102的文档:
db.comment.find({userId:{$nin:["101","102"]}})
And 条件
db.col.find({key1:value1, key2:value2})
Or 条件
db.col.find(
{
$or: [
{key1: value1}, {key2:value2}
]
}
)
And 和 Or 联合使用
类似常规 SQL 语句为: ‘where thumbUp>1000 AND (userId = ‘101’ OR articleId = ‘001’)’
db.col.find({"thumbUp": {$gt:50}, $or: [{"userId": "101"},{"articleId": "001"}]})
limit()方法
db.COLLECTION_NAME.find().limit(NUMBER)
skip() 方法
db.COLLECTION_NAME.find().limit(NUMBER).skip(NUMBER)
sort() 方法
db.COLLECTION_NAME.find().sort({KEY:1})
其中 1 为升序排列,而 -1 是用于降序排列。
db.comment.find().sort({"thumbUp":-1})1
count() 方法
db.comment.count(query, options)
模糊查询
db.comment.find({content:/理/})
db.comment.find({content:/^理/})
db.comment.find({content:/理$/})
范例 | RDBMS中的类似语句 |
---|---|
db.comment.find({content:/理/}) | where content like '%理%' |
db.comment.find({content:/^理/}) | where content like '理%' |
db.comment.find({content:/理$/}) | where content like '%理' |
案例
db.comment.drop()
// 插入测试数据
db.comment.insert({_id:"1",articleId:"001",content:"说得很有道理",userId:"101",parentId:"0",publishDate:new Date(),thumbUp:1000});
db.comment.insert({_id:"2",articleId:"001",content:"楼主太有才了",userId:"102",parentId:"0",publishDate:new Date(),thumbUp:1100});
db.comment.insert({_id:"3",articleId:"001",content:"这个可以啊",userId:"103",parentId:"0",publishDate:new Date(),thumbUp:1200});
db.comment.insert({_id:"4",articleId:"002",content:"我怀疑你在开车,可我没有证据",userId:"102",parentId:"0",publishDate:new Date(),thumbUp:1300});
db.comment.insert({_id:"5",articleId:"002",content:"同上",userId:"104",parentId:"0",publishDate:new Date(),thumbUp:1400});
db.comment.insert({_id:"6",articleId:"002",content:"这个有内涵",userId:"101",parentId:"0",publishDate:new Date(),thumbUp:1500});
db.comment.insert({_id:"7",articleId:"003",content:"理论上可行",userId:"103",parentId:"0",publishDate:new Date(),thumbUp:1600});
// 条件查询
// db.集合名.find(query,projection) query-->json projection --> 指定返回值 1为返回 0 为不返回
db.comment.find({userId:"101"})
db.comment.find({userId:"101"},{articleId:1,content:1})
db.comment.find({userId:"101"},{articleId:1,content:1,_id:0})
// 多条件查询and 将多个条件写在json中
// {key1:value1,key2:value2}
db.comment.find({userId:"101",articleId:"001"})
// or 查询
// {$or:[{},{}]}
db.comment.find({$or:[{userId:"101"},{articleId:"002"}]})
// > >= < <= != gt gte lt lte ne
// {key:{$gt:value}}
db.comment.find({thumbUp:{$gt:1200}})
db.comment.find({thumbUp:{$gte:1200}})
db.comment.find({thumbUp:{$ne:1200}})
// 需要注意类型不同
db.comment.find({_id:{$lt:2}})
db.comment.find({_id:{$lt:"2"}})
// in nin
// {key:{$in:[value1,value2]}}
db.comment.find({userId:{$in:["101","102"]}})
// 模糊查询 支持正则表达式
// db.集合名.find({key:/value/}) 匹配开头 {key:/^value/} 匹配结尾 {key:/value$/}
db.comment.find({content:/理/})
db.comment.find({content:/^理/})
db.comment.find({content:/理$/})
// 统计数量
// db.集合名.count(json)
db.comment.count()
db.comment.count({userId:"101"})
//限制行数 limit
db.comment.find().limit(2)
// 跳过数据 skip
db.comment.find().skip(2)
db.comment.find().skip(2).limit(2)
// 排序
// db.集合名.find().sort({key:value}) value 为1时为升序 -1 为降序
db.comment.find().sort({thumbUp:1})
db.comment.find().sort({thumbUp:-1})
更新数据
update() 方法用于更新已存在的文档。语法格式如下:
db.表名.update(
<query>,
<update>,
[
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
]
)
参数说明:
- query : update的查询条件,类似sql update查询内where后面的。
- update : update的对象和一些更新的操作符(如 , , ,inc.$set)等,也可以理解为sql update查询内set后面的
- upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
// 更新文档
// db.集合名.update(query,update,option) query --> json update --> json option {upsert,multi}
// upsert表示如果没有查到对应的记录,那么新增一项
// multi 表示更新多个查询到的记录,默认情况下只更新一条
// 文档替换
db.comment.update({_id:"5"},{content:"我认为可行"})
// 更新字段 {$set:{key:value}}
db.comment.update({_id:"5"},{$set:{userId:"103"}})
// 更新多个字段 {$set:{key1:value1,key2:value2}}
db.comment.update({_id:"5"},{$set:{articleId:"001",thumbUp:1400}})
db.comment.update({_id:"8"},{content:"我认为可行"},{upsert:1})
// 默认情况下只更新一条
db.comment.update({userId:"101"},{$set:{thumbUp:0}})
db.comment.update({userId:"101"},{$set:{thumbUp:1}},{multi:1})
// 值递增 $inc:{key:value} value指的是更新的步长
db.comment.update({userId:"101"},{$inc:{thumbUp:10}},{multi:1})
删除数据
通过remove()方法进行删除数据,语法如下:
db.表名.remove(
<query>,
[
justOne: <boolean>,
writeConcern: <document>
]
)
参数说明:
- query :(可选)删除的文档的条件。
- justOne : (可选)如果设为 true 或 1,则只删除一个文档,如果不设置该参数,或使用默认值 false,则删除所有匹配条件的文档。
- writeConcern :(可选)抛出异常的级别。
实例:
// 删除
// db.集合名.remove(json)
db.comment.remove({_id:"5"})
db.comment.remove({userId:"101"})
db.comment.remove({})
SpringDataMongoDB快速入门
创建项目
创建项目:mongodb-demo
pom文件:
<!-- 继承Spring boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.8.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
application.yml
spring:
data:
mongodb:
host: 192.168.85.143
port: 27017
database: leadnews-comment
引导类:
package com.heima.mongo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @author syl
*/
@SpringBootApplication
public class MongoApp {
public static void main(String[] args) {
SpringApplication.run(MongoApp.class, args);
}
}
实体类准备
实体类准备,添加注解@Document
与mongodb中的集合对应上
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.math.BigDecimal;
import java.util.Date;
/**
* APP评论信息
*/
@Data
@Document("ap_comment")
public class ApComment {
/**
* id
*/
private String id;
/**
* 用户ID
*/
private Integer userId;
/**
* 用户昵称
*/
private String userName;
/**
* 文章id或动态id
*/
private Long entryId;
/**
* 评论内容
*/
private String content;
}
基本增删改查
可以使用MongoTemplate来操作
创建测试类:
package com.heima.mongodb.test;
import com.heima.mongodb.entity.ApComment;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import java.util.List;
@SpringBootTest
public class MongdbTest {
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void testAdd(){
ApComment apComment = new ApComment();
apComment.setId("123456");
apComment.setUserId(1);
apComment.setUserName("zhangsan");
apComment.setEntryId(10001L);
apComment.setContent("你真好~");
mongoTemplate.save(apComment);
}
@Test
public void testUpdate(){
// 把id为123456的评论内容修成成“你说的对”
// Query query = new Query();
// Criteria criteria = new Criteria();
// criteria.and("_id").is("123456");
// query.addCriteria(criteria);
Query query = new Query(Criteria.where("_id").is("123456"));
Update update = new Update();
update.set("content","你说的对");
update.set("userId",2); // update ap_comment set content="你说的对" ,userId=2 where _id="123456"
mongoTemplate.updateFirst(query,update,ApComment.class);
}
@Test
public void testDelete(){
// Query query = new Query(Criteria.where("_id").is("123456"));
Query query = new Query();
mongoTemplate.remove(query,ApComment.class);
}
@Test
public void testFind(){
ApComment apComment = mongoTemplate.findById("123456", ApComment.class);
Query query = new Query(Criteria.where("userId").is(1));
List<ApComment> commentList = mongoTemplate.find(query, ApComment.class);
System.out.println(commentList);
Query query1 = new Query(Criteria.where("_id").is("123456"));
ApComment apComment1 = mongoTemplate.findOne(query1,ApComment.class);
System.out.println(commentList);
Query query2 = new Query();
// query2.skip(0).limit(3);
// query2.with(Sort.by(Sort.Direction.DESC,"userId"));
PageRequest pageRequest = PageRequest.of(1-1,3,Sort.by(Sort.Direction.DESC,"userId"));
query2.with(pageRequest);
List<ApComment> apComments = mongoTemplate.find(query2, ApComment.class);
System.out.println(apComments);
}
}