数据库学习笔记(1)

数据库学习笔记(1)

2020/04/14 add 数据库查询(mongoDB)


2020/04/17 add 数据库聚合函数
2020/04/17 add 关系型数据库和非关系型数据库


2020/04/19 add 数据库事务


2020/05/08 add mongoDB


2020/05/13 add 数据库删除


2020/05/20 add redis


2020/07/20 add mongoose mongodb schemaless


2020/07/23 add 元数据


2020/09/12 add mongoDB 精准查询

2020/09/22 add mongoDB 去重


2020/12/25 add mongoDB 关联查询


2021/01/20 add DB 基本概念


2021/02/22 add BSON 和 JSON 区别


2021/05/08 add LRU 数据库冗余,反向索引


2021/09/13 add 数据库 db-driver


DB 基本概念

连接数据库的三要素

  1. 数据源 DSN(Data Source Name): 数据库类型:host=数据库的主机地址;dbname=默认的数据库名称等
  2. 用户名:username
  3. 用户密码:password

元数据

元数据(MetaData)

元数据是用来描述数据的数据(Data that describes other data)。

元数据最大的好处是,它使信息的描述和分类可以实现格式化,从而为机器处理创造了可能。

mongoose

mongoose 是 mongodb 对象建模工具,旨在异步环境中工作。

一些注意点:

彻底搞懂Mongoose中update,updateOne,updateMany和findOneAndUpdate

  • mongoose里没有findAndModify方法
  • findOneAndUpdate,实际调用的是findAndModify,这个的好处是会返回文档,设置{new: true}返回更新后的文档,默认为false.
    如果想用原生的findOneAndUpdate, 就设置mongoose.set('useFindAndModify', false);
    或者
    mongoose.connect(uri, { useFindAndModify: false });
    如果用原生findOneAndUpdate,可以设置returnNewDocument属性,返回修改后的值

关于 findOneAndUpdate 中常用的 修改器:MongoDB之 关 键 字 , 以 及 关键字,以及 修饰器 s e t , set, set,inc, p u s h , push, push,pull,$pop

查询符合对象数组中某个对象的值

// 数据结构
[
    {
        _id:'0',
        publisher:{
            uid:'123',
        }
        subscriber:[
            {
                mobile:'xxxx',
                email:'xxa@163.com'
            },
            {
                email:'xxb@163.com'
            }
        ]
    },
    {
        _id:'1',
        publisher:{
            uid:'456',
        }
        subscriber:[
            {
                email:'xxa@163.com'
            },
            {
                email:'xxb@163.com'
            }
        ]
    }, 
    {
        _id:'2',
        publisher:{
            uid:'456',
        }
        subscriber:[
            {
                email:'xxa@163.com'
            },
        ]
    },
    {
        _id:'3',
        publisher:{
            uid:'456',
        }
        subscriber:[
            {
                phone:'18311109091'
                email:'xxa@163.com'
            },
            {
                email:'xxb@163.com'
            }
        ]
    },     
]

需求: 查出订阅者邮箱是xxa@163.com的所有通知历史。此时若使用 subscriber:{email:'xxa@163.com'}进行查询只会查出来_id:2 的数据,此时应该这么查询:

reference:MongoDB操作符之$elemMatch

// shell
// 注意这种查询方式会查出来 subscriber 这个数组中任何有一个元素满足即返回
db.getCollection('notices').find({"subscriber.email":"xxa@163.com","subscriber.phone":"18222308101"})
// 注意 $elemMatch 有更准确用法:The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria. 即只会返回完全满足 email 和 phone 条件的元素
db.getCollection('notices').find({subscriber:{$elemMatch:{email:"xxa@163.com",phone:"18222308101"}}})

// 有关 mongoose api 基于以上进行相应改变即可

数据库删除

逻辑删除

逻辑删除记录,不会直接删除数据库中的数据,仅是通过某些手段屏蔽被逻辑删除的数据在前台的显示,不会释放物理空间,并且还可以从数据库中查得数据。

物理删除

物理删除记录,即是会将数据库中的数据记录直接清除(也可以说是磁盘上的删除),会释放出物理空间,也将不能再从数据库中搜索到删去的数据记录;

后记

一般来讲大部分公司都采用逻辑删除的方式:对数据记录用处极大

逻辑删除真的不是一个好的设计

mongoDB

__v字段

mongodb中的__v字段

“__v” 是 “versionKey"的简写,当每一个文档由mongoose创建时就会自动添加,代表这该文档的版本,此属性可配置修改,默认为“__v”,

作用是可以在"save文档"时作为一个查询条件,避免在"取出数据"到"save数据"的这段时间内,数据被其他进程修改而导致冲突。

MongoDB 查询

模糊查询

Evaluation Query Operators
使用 $regex 操作符以及 PCRE 即可

精准查询

但有的时候也会用到精准查询:
stackoverflow 查询之后通常用这种 text search 的方式进行查询:

建立索引 ==> 查询

注:需要注意的是可以通过对单个字段建立索引进行查询,因此并不意味着 text是全文检索

Text Indexes

关联查询

shell 可以参考 $lookup

mongoose 可以参考 virtualType 与 populate

schemaless vs schemafree

Is MongoDB really Schemaless?

mongodb schemafree 即:插入额外的字段或者说列,不存在即允许插入,不会禁用。实际上这跟 mongdodb 本身是一个 NOSQL db 有关,which does not use the concept of tables and columns, instead of which it uses the concept of documents and collections. All the referential data with respect to different modules will be stored as one collection. More over the BSON data structure used by MongoDB can easily have varying sets of data and fields with different types.
When we say schemaless, we actually mean dynamically typed schema, as opposed to statically typed schemas as available in RDBMS(SQL) databases. JSON is a completely schema free data structure, as opposed to XML which allows you to specify XSD if you need.

但针对 schema-free 进行限制 save 操作的需求该怎么处理
image
image
image

MongoDB 去重

distinct 去重

MongoDB distinct() 指定字段去重

manual

注: 但实际上这种去重方式有其局限性就是不能超过 16MB,否则会报类似错 Error: distinct too big, 16mb cap

去重

MongoDB 的 _id

通常,在一个集合中,没写入一行数据都会自动生成一个唯一标识 _id,它为什么这么轻量又能保证全局唯一的呢?

Mongodb 中的 _id 和 ObjectId

前4 个字节是从标准纪元开始的时间戳,单位为秒。这会带来一些有用的属性。时间戳,与随后的. 5 个字节组合起来,提供了秒级别的唯一性。由于时间戳在前,这意味着ObjectId 大致会按照插入的顺序排列。这对于某些方面很有用,如将其作为索引提高效率,但是这个是没有保证的,仅仅是“大致”。这4 个字节也隐含了文档创建的时间。绝大多数驱动都会公开一个方法从ObjectId 获取这个信息。因为使用的是当前时间,很多用户担心要对服务器进行时间同步。其实没有这个必要,因为时间戳的实际值并不重要,只要其总是不停增加就好了(每秒一次)。

接下来的3 字节是所在主机的唯一标识符。通常是机器主机名的散列值。这样就可以确保不同主机生成不同的ObjectId,不产生冲突。

为了确保在同一台机器上并发的多个进程产生的ObjectId 是唯一的,接下来的两字节来自产生ObjectId 的进程标识符(PID)

前9 字节保证了同一秒钟不同机器不同进程产生的ObjectId 是唯一的。后3 字节就是一个自动增加的计数器,确保相同进程同一秒产生的ObjectId 也是不一样的。同一秒钟最多允许每个进程拥有2563(16 777 216)个不同的ObjectId。

MongoDB 的 cursor

游标是什么?

通俗的说,游标不是查询结果,而是查询的一个返回资源或者接口,通过
这个接口,可以逐条读取数据。这里尤其适用于在查询大量数据的场景。

toArray 的优化或者说替代的高效方式有哪些?

mongodb 16MB 到底限制了哪些操作?

众所周知,mongodb 有单个文档 16MB 的限制,实际操作中受限于这个限制的操作其实多于写操作,甚至还包含读操作,query 较大操作?

docs

How to set Buffer offset range in MongoDB, Its not allowing to upload more than 16MB file in BSON Object?

起因是解决用户问题时发现,当用户查询数据量较大时同样会出现如上所示的问题 [ERR_OUT_OF_RANGE]: The value of "offset" is out of range. It must be >= 0 && <= 17825792. Received

  • 一种揣测是 MongoDB 一次查询返回数据也是包成一个 BSON,因此同样是受控制的。

其他比如 query 体过大导致报错的现象,可以参考:

Mongodump crash if query file is to large

BSON 和 JSON 的区别

references:

BSON的介绍及BSON与JSON的区别

BSON数据格式

  • BSON( Binary Serialized Document Format) 是一种二进制形式的存储格式,其是一种类 json 的一种二进制形式的存储格式,它和 JSON 一样,支持内嵌的文档对象和数组对象,但是 BSON 有 JSON 没有的一些数据类型,如 Date 和 BinData 类型。
  • BSON 是 schema less 的,作为 MongoDB 的数据存储格式,因此 MongoDB 数据存储也是 schema less 的。
  • BSON 有更快的遍历速度,更容易操作修改,增加了额外的数据类型。

数据库事务

数据库事务

概念

数据库事务( transaction)是访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

性质

  1. 原子性(Atomicity):事务中的全部操作在数据库中是不可分割的,要么全部完成,要么全部不执行。
  2. 一致性(Consistency):几个并行执行的事务,其执行结果必须与按某一顺序 串行执行的结果相一致。
  3. 隔离性(Isolation):事务的执行不受其他事务的干扰,事务执行的中间结果对其他事务必须是透明的。
  4. 持久性(Durability):对于任意已提交事务,系统必须保证该事务对数据库的改变不被丢失,即使数据库出现故障。

事务的ACID特性是由关系数据库系统(DBMS)来实现的,DBMS采用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所作的更新,如果某个事务在执行过程中发生错误,就可以根据日志撤销事务对数据库已做的更新,使得数据库同滚到执行事务前的初始状态。

对于事务的隔离性,DBMS是采用锁机制来实现的。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。

关系型数据库 vs 非关系型数据库

工作原因,平常会比较多用mongoDB,而它实际区别于以前用过的譬如mysql oracle等

关系型数据库和非关系型数据库举例

常见的关系型数据库和非关系型数据及其区别

聚合函数 DB

深入理解数据库当中的聚合函数

SQL中的聚合函数介绍

聚合函数是什么

聚合函数对一组值执行计算并返回单一的值。

在数据库当中,函数分为两种:单行函数和多行函数,相应概念如下:
单行函数:每一行返回一个数值(如lower)
多行函数:多行返回一个数值(如count)
聚合函数:多行函数,即表中的多条记录返回至一个数值,通常用于分组的相关信息。

常见的聚合函数

聚合函数的分类:(常用的5个)

  • count:
    • count(*):统计表中所有记录的个数
    • count(列名):统计一列中值的个数,其中重复的记录也会被当做有效的记录。
    • count(distinct 列名):统计一列中值的个数,其中重复的记录只会被记录一次。
  • sum(列名):计算一列值的总和。
  • avg(列名):计算一列值的平均值。
  • max(列名):计算一列值中的最大值。
  • min(列名):计算一列值中的最小值。

我认为只要记住count为统计一列中值的个数就可以了,因为里面毕竟是distinct的用法。

注意点

  1. 聚合函数同order by、distinct、top等都是一样的,都是作用于最终的结果集合的,而不是最用于单行元组的,所以在SQL语句的处理过程当中一定要分清该关键字是作用域单行记录的,还是作用于最终的结果集合的。
  2. 在聚合函数遇到空值的时候,除count(*)外,所有的聚合函数都会跳过空值而只处理非空值。
  3. 单行函数和多行函数不能混合使用。
  4. 如果未对查询结果进行分组,聚集函数将作用于整个查询结果,而分组后聚集函数将作用于每一个组,即每一个组都有一个函数值。

数据库查询mongodb

模糊查询

{name:/xxx/} // 包含
{name:/^xxx/} // 以xxx开头
{name:/xxx^/} // 以xxx结尾
{name:/xxx/i} // 忽略大小写

条件查询

db.collections.find({'name':{$in:['tommy'],['Ammy']}) // 查询名字叫Tommy 和 Ammy的人

查询是否含有某个字段

mongodb中find n e n u l l 与 ne null 与 nenullexists的区别

$ne:null $exists:true的区别

数据库 tips

mongoose doc.save 更新问题

且看 mongoose 文档 Since it is a schema-less type, you can change the value to anything else you like, but Mongoose loses the ability to auto detect and save those changes. To tell Mongoose that the value of a Mixed type has changed, you need to call doc.markModified(path), passing the path to the Mixed type you just changed. 因此在对具体 doc 进行更新时可以将其标记为 markModified

mongoose复杂类型doc.save()无法更新的问题

mongoose autoCreate

mongoose doc

区别于 mongoClient, mongoose 做了一部分优化,那就是可以不在建立 model 的时候自动创建 collection

'autoCreate': Set to true to make Mongoose call Model.createCollection() automatically when you create a model with mongoose.model() or conn.model(). This is useful for testing transactions, change streams, and other features that require the collection to exist.

LRU

其实前文已经在 Redis 中提过 LRU,LRU 是 Redis 的一种逐出策略,当然平常业务中如果不使用 Redis 如何做简单的缓存呢,答案是可以采用 quick-lru 等包实现。

这篇文章概述了简单的 LRU 实现方式: 主要采用双向链表和 hashMap(至于为什么不用单向链表是因为单向链表删除尾节点的时候需要遍历整个链表显而易见效率是低的)
LRU 原理和 Redis 实现

db-driver

What is a Database Driver? Access Database in VS Code. R. Python. Java

db driver 可以看做是一个连接数据库和其他系统之间的一个适配器,它实现了 ODBC 或 JDBC 数据量连接协议。

A database driver is a computer program that implements a protocol (ODBC or JDBC) for a database connection.

connection pool

connection_pool

Connection Pooling with MongoDB

数据库连接池的作用与原理

在软件工程中,连接池是维护数据库连接的缓存,可以理解成预先在池子中放进去一些连接,需要时从连接池取出即可,使用完毕再放回去以便将来需要对数据库的请求时可以复用该连接。 连接池用于提高在数据库上执行命令的性能。 在连接池中,创建连接后,将其放入池中并再次使用,这样就不必建立新连接。 如果所有连接都被使用,则会建立一个新连接并将其添加到池中。 连接池还减少了用户必须等待建立到数据库的连接的时间。

node-mongodb-native(node mongodb driver) 支持 connection pool,普通使用中我们一般在应用启动时即建立连接(或单例模式),此后整个应用复用这一个连接进行各种数据库操作。

个人理解: 当高并发的时候,此时会由于连接池中的一个连接在使用而需要新建一个连接再放入到连接池中进行使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现
C语言是一种广泛使用的编程语言,它具有高效、灵活、可移植性强等特点,被广泛应用于操作系统、嵌入式系统、数据库、编译器等领域的开发。C语言的基本语法包括变量、数据类型、运算符、控制结构(如if语句、循环语句等)、函数、指针等。下面详细介绍C语言的基本概念和语法。 1. 变量和数据类型 在C语言,变量用于存储数据,数据类型用于定义变量的类型和范围。C语言支持多种数据类型,包括基本数据类型(如int、float、char等)和复合数据类型(如结构体、联合等)。 2. 运算符 C语言常用的运算符包括算术运算符(如+、、、/等)、关系运算符(如==、!=、、=、<、<=等)、逻辑运算符(如&&、||、!等)。此外,还有位运算符(如&、|、^等)和指针运算符(如、等)。 3. 控制结构 C语言常用的控制结构包括if语句、循环语句(如for、while等)和switch语句。通过这些控制结构,可以实现程序的分支、循环和多路选择等功能。 4. 函数 函数是C语言用于封装代码的单元,可以实现代码的复用和模块化。C语言定义函数使用关键字“void”或返回值类型(如int、float等),并通过“{”和“}”括起来的代码块来实现函数的功能。 5. 指针 指针是C语言用于存储变量地址的变量。通过指针,可以实现对内存的间接访问和修改。C语言定义指针使用星号()符号,指向数组、字符串和结构体等数据结构时,还需要注意数组名和字符串常量的特殊性质。 6. 数组和字符串 数组是C语言用于存储同类型数据的结构,可以通过索引访问和修改数组的元素。字符串是C语言用于存储文本数据的特殊类型,通常以字符串常量的形式出现,用双引号("...")括起来,末尾自动添加'\0'字符。 7. 结构体和联合 结构体和联合是C语言用于存储不同类型数据的复合数据类型。结构体由多个成员组成,每个成员可以是不同的数据类型;联合由多个变量组成,它们共用同一块内存空间。通过结构体和联合,可以实现数据的封装和抽象。 8. 文件操作 C语言通过文件操作函数(如fopen、fclose、fread、fwrite等)实现对文件的读写操作。文件操作函数通常返回文件指针,用于表示打开的文件。通过文件指针,可以进行文件的定位、读写等操作。 总之,C语言是一种功能强大、灵活高效的编程语言,广泛应用于各种领域。掌握C语言的基本语法和数据结构,可以为编程学习和实践打下坚实的基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值