MySQL与MongoDB

1.MySQL是一个关系型数据库管理系统(Relational Database Management System:RDBMS))由于瑞典[MySQL AB](https://baike.baidu.com/item/MySQL AB/2620844?fromModule=lemma_inlink) 公司开发,属于 Oracle 旗下产品。

常用的关系数据库管理系统产品是OracleIBMDB2和微软的SQL Server。

索引是一种特殊的文件(InnoDB 数据表上的索引是表空间的一个组成部分),它们包含着对数据表里所有记录的引用指针。索引不是万能的,索引可以加快数据检索操作,但会使数据修改操作变慢每修改数据记录,索引就必须刷新一次。为了在某种程度上弥补这一缺陷,许多 SQL 命令都有一个 DELAY_KEY_WRITE 项。这个选项的作用是暂时制止 MySQL 在该命令每插入一条新记录和每修改一条现有之后立刻对索引进行刷新,对索引的刷新将等到全部记录插入/修改完毕之后再进行。在需要把许多新记录插入某个数据表的场合,DELAY_KEY_WRITE 选项的作用将非常明显。另外,索引还会在硬盘上占用相当大的空间。因此应该只为最经常查询和最经常排序的数据列建立索引。

1.添加索引后,查询速度可以更快的原因是因为索引可以在某个字段上创建一个排序的快速访问结构。在MySQL中,索引是一种特殊的数据结构,它可以加速数据的查找和访问速度。当你在关系型数据库中执行一个查询时,MySQL会尽可能地使用索引来加速查询。

2.当你在查询中使用了索引字段时,MySQL会使用索引数据结构来快速定位符合条件的数据。这是因为索引会按照特定的顺序排序,并且可以快速定位到符合条件的数据。这个过程类似于使用字典查找单词,索引就像是字典中的目录,可以让你快速找到需要的内容。

3.索引可以减少数据库的扫描量,因为它可以帮助MySQL跳过不需要的行。在使用索引时,MySQL会首先检查索引,然后只扫描满足条件的行。这样可以减少需要扫描的行数,从而提高查询效率。

但是,在创建索引时需要注意,索引会占用磁盘空间,并且可能会降低插入和更新操作的速度。因此,需要仔细考虑在哪些字段上创建索引,并避免过多的索引。

2.MongoDB是一个开源的文档型数据库管理系统,采用分布式文件存储方式。它将数据存储为一个文档,数据结构非常灵活,可以存储复杂的层级结构数据。MongoDB的数据模型支持动态查询、索引、内嵌文档、动态数组等特性,使得数据的存储和检索变得非常方便和高效。MongoDB还具有很好的扩展性和可用性,能够支持海量数据存储和高并发访问。此外,MongoDB还提供了丰富的工具和API,可以轻松地进行数据的可视化和分析。

#常用命令
1
2
3
4
5
6
7
8
9
show dbs	//显示所有数据库

use 数据库名 //进入指定数据库

db //显示当前数据库
show collections //展示所有集合
CRDU

db.<collection>.insert()

查询文档

查询集合 users 中的所有文档:

1
db.users.find()

查询集合 usersage 大于 18 的文档:

1
db.users.find({age: {$gt: 18}})

插入文档

向集合 users 中插入一条文档:

1
db.users.insertOne({name: "Alice", age: 20})

向集合 users 中插入多条文档:

1
db.users.insertMany([{name: "Alice", age: 20}, {name: "Bob", age: 25}])

更新文档

将集合 usersname 为 “Alice” 的文档的 age 值改为 21:

1
db.users.updateOne({name: "Alice"}, {$set: {age: 21}})

将集合 usersage 大于等于 20 的文档的 age 值都增加 1:

1
db.users.updateMany({age: {$gte: 20}}, {$inc: {age: 1}})

删除文档

删除集合 usersname 为 “Alice” 的文档:

1
db.users.deleteOne({name: "Alice"})

删除集合 usersage 大于等于 30 的文档:

1
db.users.deleteMany({age: {$gte: 30}})

创建索引

在集合 users 中为 name 字段创建索引:

1
db.users.createIndex({name: 1})

聚合查询

对集合 orders 中的数据进行聚合,计算每个用户的订单总金额:

1
2
3
db.orders.aggregate([
{$group: {_id: "$user_id", total_amount: {$sum: "$amount"}}}
])

分组查询

对集合 orders 中的数据按照用户分组,并计算每个用户的订单总金额:

1
2
3
4
5
db.orders.group({
key: {user_id: 1},
reduce: function(prev, cur) {prev.total_amount += cur.amount},
initial: {total_amount: 0}
})

计数

计算集合 users 中的文档数量:

1
db.users.count()

排序

查询集合 users 中的所有文档,并按照 age 字段降序排序:

1
db.users.find().sort({age: -1})

分页查询

查询集合 users 中的第 11 到 20 条文档:

1
db.users.find().skip(10).limit(10)

$or使用

1
2
db.emp.find({$or:[{sal:{$lt:1000}},{sal:{$gt:2500}}]});
//查询工资小于1000或大于2500的员工

MongoDB处理以亿为量级的数据

MongoDB适合存储大规模数据,它的存储方式是基于文档的,而不是基于表的。在MongoDB中,数据以文档的形式存储在集合(collection)中,每个文档都是一个键值对的集合,可以包含嵌套文档、数组和其他复杂数据类型。

当需要存储亿级别的数据时,需要考虑集合的分片(sharding)和索引(indexing)两个方面。

  1. 分片:MongoDB支持将数据分片存储在多个服务器上,以支持大规模数据存储和高并发查询。分片可以按照某个字段范围或哈希值进行分配,每个分片都是一个独立的MongoDB实例,可以水平扩展。
  2. 索引:索引可以提高查询的效率,特别是在大规模数据下。MongoDB支持多种类型的索引,如单键索引、组合索引、全文索引、地理位置索引等。在设计索引时需要考虑查询的频率和复杂度,以及索引的大小和内存占用。

分片示例:假设我们有一个用户行为日志的数据库,其中包含了用户ID、行为类型、行为时间等字段。我们想要将这个数据库进行分片,以提高查询性能和可扩展性。

  1. 定义分片键:我们可以选择用户ID作为分片键,因为用户ID是唯一的,而且用户行为可能会集中在某些用户身上,如果按照用户ID分片,可以尽可能地将数据均匀地分散到不同的分片节点上。

  2. 部署分片节点:假设我们有3台服务器可以用于存储分片数据。我们可以将用户ID分别按照范围分为3个部分,例如0-9999、10000-19999、20000-29999三个范围,然后将这三个范围的数据分别存储到三个不同的分片节点上。

  3. 路由查询请求:当客户端发送一个查询请求时,如果查询条件中包含了用户ID,我们可以根据用户ID的值将查询请求路由到对应的分片节点上。例如,如果查询条件中的用户ID为12345,则查询请求将被路由到存储范围为10000-19999的分片节点上。

  4. 聚合查询结果:如果查询请求涉及多个分片节点,我们需要将各个节点的查询结果合并起来,并返回给客户端。例如,如果我们想要查询所有行为时间在2021年1月1日到2021年1月31日之间的用户行为记录,这个查询请求可能会涉及到多个分片节点。我们需要将各个节点的查询结果合并起来,然后再返回给客户端。

需要注意的是,在实际应用中,可能会遇到一些分片时的问题,例如数据不均匀、数据迁移、数据一致性等,需要采取一些措施来解决。