MongoDB入门学习(二):MongoDB的基本概念和数据类型

上一篇讲了MongoDB的安装和管理,其中涉及到了一些概念,数据结构还有一些API的调用,不知道的没关系,其实很简单,这篇会简单介绍一下。

1.文档

文档是MongoDB的核心概念,多个键值对有序的放在一起就是一个文档,文档是MongoDB存储数据最基本的数据结构。对MongoDB都是以文档的形式来操作的,使用了一种类似JSON的二进制BSON数据格式,对API的调用都是传的文档参数。每种编程语言都有标示文档的数据结构,比如java的map,lua的table,python的dict等等,但是都是差不多的,一个键对应一个值。相对于MySQL而言,MongoDB的文档就相当于MySQL表中的一行数据。

写法1
>db.people.insert({"name" : "Mary", "age" : 10})
写法2
>person1 = {"name" : "Mary", "age" : 10}
>db.people.insert(person1)

上面这两种写法是一样的,都是将一个文档插入到数据库的people集合中。只是第二种写法用了一个变量person1来表示这个要插入的文档。

文档中键值对是有序的,下面这两个文档是不一样的:

doc1 = {"name" : "Mary", "age" : 10}
doc2 = {"age" : 10, "name" : "Mary"}

文档的键必须是字符串类型,但是值可以是很多的类型,这个后面会说到。而且文档是区分大小写的,name键和Name键是有区别的。文档中的键必须是唯一的。

2.集合

上面说到people集合,MongoDB的集合就相当于MySQL的一个表table,MongoDB列出所有的集合可以是show tables,也可以是show collections。集合是一组文档,而且是无模式的,一个集合中的文档可以是各式各样的:

db.people.insert({"name" : "Mary", "age" : 10})
db.people.insert({"country" : "USA", "languge" : "english"})

如上面给people集合中插入了两个文档,但是这两个文档是完全不同的,键都不一样,这样的话,那不是所有的文档都可以放在一个集合中,确实是这样的,但是这样确实是有问题的,当集合大到一定程度的时候速率就会变的很慢,而且查询效率非常低,而且对于管理方面是非常复杂的,所以我们也要为数据库划分不同的集合。

上一篇看到了很多的集合,people啊,system.indexes啊,system.users啊等,集合的命名也有一定的限制的,首先不能为空"",也不能含有空字符,不能有保留字符$,system开头的就更不行了,这个是未系统集合保留的前缀。我们只要用一些很普通易懂的命名就好了,对于我们自己的管理和操作也是很简单的。

MongoDB还有一个子集合的概念,就是一个集合包含几个集合,这样也是便于管理,比如上面将people的基本信息和国籍信息这样放在一个people集合中有点勉强,可以直接写成一个文档放进去,也可以用两个子集合,一个表示基本信息baseinfo,一个表示国籍信息countryinfo:

db.people.baseinfo.insert({"name" : "Mary", "age" : 10})
db.people.countryinfo.insert("country" : "USA", "languge" : "english")

这个例子有点牵强,但是这样也容易理解。从上面可以看出,我们还没有创建people这样一个集合就可以直接insert,这样对于使用MySQL的人来说有点难以理解,表都没创建就给它插入数据,更离谱的是我们数据库都没创建,就可以直接使用任何数据库use anyDatabase:

> show dbs
admin   0.078GB
dhh_tp  0.078GB
local   0.078GB
test    0.078GB
> use temple
switched to db temple
>db
temple
> show collections
> db.people.insert({"name" : "Mary", "age" : 10})
WriteResult({ "nInserted" : 1 })
> show tables
people
system.indexes
> db.people.find()
{ "_id" : ObjectId("539137ce90c0386ead60e4f4"), "name" : "Mary", "age" : 10 }

看吧,show dbs查看所有的数据库,里面根本就没有temple,但是在直接使用的时候却不会报错,用db查看使用的哪个数据库的时候也确实是使用的temple,show collections查看所有的集合的时候一个集合都没有,因为这个数据库都不存在,哪来的表。然后直接给people集合中插入数据也不会报错,事后查询发现生成了people集合,而且还有个system.indexes集合,数据也确实插进了people集合,system.indexes存储的是集合中的索引,这个以后说。MongoDB会在插入数据的时候检查有没有这样一个数据库这样一个集合,如果不存在的话会自动创建,就不用我们自己创建集合,还要定义那么多的字段,字段的数据类型,长度以及能否为空,唯一键等等,非常的方便实用。

3.数据库

MongoDB中多个文档组成一个集合,那么多个集合就组成一个数据库,比如上面people和system.indexes组成temple数据库。MongoDB中每个数据库之间是相互独立的,都有独立的权限,而且都是存放在不同的文件中的。

MongoDB数据库的命名也有一定的限制的,不能有空格或者空字符,也不能包括特殊符号,应该全部小写,最多64字节,一点很重要,数据库名最终会变成系统中的文件的,你可以打开data/db来看一下,里面就会有和你数据库一样名字的文件,它们里面就是数据库的数据,数据库的命名也应该是普通的易懂的。而且不能使用某些名字,比如admin,这是root数据库不用多说,local,这个数据库是不能被复制的,以后说,config,和分片有关的,这几个都是保留的数据库名。

启动MongoDB服务器上一篇也介绍过了。启动MongoDB客户端上一篇也说过,执行mongo指定选项就可以了,在这里可以执行任何javascript程序,也可以对数据库进行一般的操作,增insert删remove查find改update之类的,这个后面会说到的。也有删除集合和数据库的命令:

> show tables
people
system.indexes
> db.people.drop()
true
> show tables
system.indexes
> use temple
switched to db temple
> db
temple
> db.dropDatabase()
{ "dropped" : "temple", "ok" : 1 }
> show dbs
admin   0.078GB
dhh_tp  0.078GB
local   0.078GB
test    0.078GB

db.dropDatabase()删除使用的数据库,db.people.drop()删除people集合。这些API用起来都很简单。

4.数据类型

MongoDB有着非常丰富的数据类型,如上面的name字段是字符串,age字段是数字,当然不止这两种。JSON只有6中数据类型,null,布尔,数字,字符串,数组和对象。MongoDB在JSON的基础上添加了一些其他的数据类型,下面来看看MongoDB的数据类型:

null:用于表示控制或者不存在的字段,如:{"x" : null}。

布尔:只有两个值true和false。

32位整数:shell中这个类型不可用,javascript仅支持64位浮点数,所以32位整数会被自动转换。

64位整数:shell中这个类型不可用,shell会使用一个特殊的内嵌文档来显示64位整数。

64位浮点数:shell中的数字都是这个类型,{"x" : 3.14}和{"x" : 3}都是浮点数。

因为javascript只有一种数字类型就是64位浮点型,所以MongoDB中从shell的来的数字都被当做64位浮点型,而MongoDB中支持三种数字类型,所以用shell修改过数据库中的数据后都会被转换成64位浮点型。64位整数并不能精确的表示64位浮点型,如果MongoDB中存入了一个64位整数,在shell中查看时,如果能够表示64位浮点型那就用一个键的内置文档显示而且这个值是精确的,否则,他会显示一个多键内嵌文档,表示可能不精确。

如果是64位整数3,那么在shell中查询显示会是这个样子:

db.nums.findOne()
{
        "_id" : ObjectId("4c0beecfd096a2580fe6fa08"),
        "myInteger" : {
                "floatApprox" : 3
    }
}

如果是64位整数9223372036854775807,那么在shell中查询显示会是这个样子:

db.nums.findOne()
{
        "_id" : ObjectId("4c0beecfd096a2580fe6fa08"),
        "myInteger" : {
                "floatApprox" : 9223372036854775807,
                "top" : 2147483647,
                "bottom" : 4294967295
    }
}

top和bottom分别表示高32位和低32位。

字符串:UTF-8字符串都可表示为字符串类型的数据,如:{"name" : "Mary"}。

符号:shell不支持这种类型,shell会将数据库中的符号类型转换成字符串。

对象id:对象id是文档的12字节的唯一ID。

MongoDB中存储的文档必须有一个键"_id",这个键可以是任意类型的,默认是ObjectId对象,当我们存入文档时不指定该键,那么MongoDB会自动添加这样一个键值对,这个值是唯一标识,ObjectId使用12字节的存储空间。

日期:日期类型存储的是从标准纪元开始的毫秒数,不存储时区,如:{"x" : new Date()}。

javascript中Date对象用作MongoDB的日期类型,创建日期对象要用new Date()而不是Date(),返回的是对日期的字符串表示,而不是真正的Date对象。

正则表达式:文档中可以包含正则表达式,采用javascript的正则表达式语法,如:{"x" : /foobar/i}。

代码:文档中还可以包含javascript代码,如:{"x" : function(){/*...*/}}。

二进制数据:二进制数据可以由任意字节的串组成,不过shell中无法使用。

最大值:BSON包括一个特殊类型,表示可能的最大值,shell中没有这个类型。

最小值:BSON包括一个特殊类型,表示可能的最小值,shell中没有这个类型。

未定义:文档中也可以使用未定义类型,如:{"x" : undefined}

数组:值的集合或者列表可以表示成数组,数组中的元素可以是不同类型的数据,如:{"x" : ["a", "b", "c", 20]}。

内嵌文档:文档可以包含别的文档,也可以作为值嵌入到父文档中,如:{"x" : {"foo" : "bar"}}。

在我目前用的情况,布尔,数字,字符串,日期,数组和内嵌文档是用的最多的。

MongoDB入门学习(二):MongoDB的基本概念和数据类型

时间: 2024-10-05 05:07:53

MongoDB入门学习(二):MongoDB的基本概念和数据类型的相关文章

MongoDB入门学习(三):MongoDB的增删查改

对于我们这种菜鸟来说,最重要的不是数据库的管理,也不是数据库的性能,更不是数据库的扩展,而是怎么用好这款数据库,也就是一个数据库提供的最核心的功能,增删查改. 因为MongoDB存储数据都是以文档的模式,所以在操作它的数据时,也是以文档为单位的.那么我们实现增删查改也是以文档为基础,不知道文档是什么的同学可以看看上篇介绍的基本概念. 1.插入文档 向MongoDB集合中插入文档的基本方法是insert: 单个插入 > document = {key : value} > db.collecti

MongoDB入门学习(四):MongoDB的索引

上一篇讲到了MongoDB的基本操作增删查改,对于查询来说,必须按照我们的查询要求去集合中,并将查找到的结果返回,在这个过程中其实是对整个集合中每个文档进行了扫描,如果满足我们的要求就添加到结果集中最后返回.对于小集合来说,这个过程没什么,但是集合中数据很大的时候,进行表扫描是一个非常恐怖的事情,于是有了索引一说,索引是用来加速查询的,相当于书籍的目录,有了目录可以很精准的定位要查找内容的位置,从而减少无谓的查找. 1.索引的类型 创建索引可以是在单个字段上,也可以是在多个字段上,这个根据自己的

Elasticsearch入门教程(二):Elasticsearch核心概念

原文:Elasticsearch入门教程(二):Elasticsearch核心概念 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/vbirdbest/article/details/79200022 基本概念介绍 Elasticsearch是一个基于Lucene构建的开源.分布式.RESTful的搜索引擎,能够实现近实时(NRT)搜索,稳定.可靠.安装方便.Elasticsearch 不

Objective C 快速入门学习二

Objective-C 类.对象.方法 1.编写一个复数类: #import <Foundation/Foundation.h>@interface Complex: NSObject //类声明,Complex继承NSObject { int iReal;//成员变量声明,在括号内 int iImag; } //成员函数声明,在括号外 -(void) print; -(void) setReal : (int) n; -(void)setImag : (int) d; @end //@int

SpringMVC入门学习(二)

SpringMVC入门学习(二) ssm框架 springMVC 在上一篇博客中,我简单介绍了一下SpringMVC的环境配置,和简单的使用,今天我们将进一步的学习下Springmvc的操作. model.addAttribute()的使用 model接口的源代码: 由图可知,在addAttribute()中有两种入参方式,一种是指明名字var1,一种是不指明名字var1.在不指明名字中,会通过相近的去寻找. 在addAttribute()中,我们可以放任何对象: 首先先导入jsp标签maven

Python入门学习:1.变量和简单的数据类型

python入门学习:1.变量和简单的数据类型 关键点:变量.字符串.数字 1.1 变量的命名和使用1.2 字符串1.3 数字1.4 注释 1.1 变量的命名和使用 ??变量,顾名思义是一个可变的量,每个变量都存储一个值--与变量关联的信息. 1message = "hello world!"2# message 是一个变量3print(message) ??在python中使用变量时,需要遵循一些规则和指南. 变量名只能包含字母.数字和下划线.变量名可以字母或者下划线打头,但不能以数

git入门学习(二):新建分支/上传代码/删除分支

一.git新建分支,上传代码到新的不同分支 我要实现的效果,即是多个内容的平行分支:这样做的主要目的是方便统一管理属于同一个内容的不同的项目,互不干扰.如图所示: 前提是我的github上已经有webpack_test项目了,我是在这个项目的基础上新建其他的分支并开展工作的.如图: 如果你对如何新建webpack_test项目不清楚,请参考我的前一篇文章:git入门学习(一):github for windows上传本地项目到github,操作步骤如下: 1.1.保留webpack_test项目

activiti入门学习二

一.上一篇入门学习的地址 https://www.cnblogs.com/yangk1996/p/10878449.html 二.单机演示Demo 12.使用UEL表达式动态增加流程处理人 从新创建一个流程,使其Assignee变成表达式的.然后从新创建流程. * @Description: 启动流程实例,动态设置assignee * @date: 2019/6/23 20:28 */ public class AssigneeUel { public static void main(Stri

Java入门(二):注释和基本数据类型

上次通过eclipse在控制台输出了hello world,是不是有点小激动啊,今天接着介绍Java基础知识. 一.Java注释 1.Java注释语句不会被编译器运行,不用担心代码因为许多注释语句显得臃肿而影响程序运行速度. 2.Java注释有三种写法. 一是双斜杠 // .需要注掉哪一行就添加到哪一行前面,在添加中文注释时,在双斜杠//后面添加一个空格,在写注释内容,这是编码规范. 二是 /* */ .这样的注释标记可以注释多行,就不必每行都使用单行注释. 三是 /** */ .这样的注释也可