MongoDB初探-基本概念与数据类型
一、基本概念 1、文档:MongoDB是基于文档(Document)的NoSQL数据库。文档是MongoDB中数据的基本单元,非常类于关系数据库中的行(比行要复杂)。 文档由多个键对组成,它们具有以下特性: a、文档中的键/对是有序的(通常文档中键的顺序并不重要)。 b、文档中的
一、基本概念
1、文档:MongoDB是基于文档(Document)的NoSQL数据库。文档是MongoDB中数据的基本单元,非常类似于关系数据库中的行(比行要复杂)。
文档由多个键值对组成,它们具有以下特性:
a、文档中的键/值对是有序的(通常文档中键的顺序并不重要)。
b、文档中的值不仅可以是双引号里的字符串,还可以是其他几种数据类型(甚至可以是整个嵌入的文档)。
c、文档的键是字符串。除了下面少数例外情况,键可以使用任意UTF-8字符。
I、键不能含有\0(空字符),这个字符用于表示键的结尾。
II、点(.)和$有特殊的意义,只能在特定环境下使用。
III、以下划线"_"开头的键为保留键。
d、键/值区分类型和大小写。
e、键不能重复。
2、集合:集合就是一组文档,类似于关系型数据库中的表。MongoDB的集合有以下特性:
a、无模式。集合无模式意味着一个集合里的文档可以是各式各样的,但最好根据数据特征或业务需求划分成多个集合。
b、命名,通过名字来标识集合。集合名可以是满足下列条件的任意UTF-8字符串:
I、集合名不能是空字符串。
II、集合名不能含有\0字符(空字符),这个字符表示集合名的结尾。
III、集合不能以“system.”开头,这是为系统集合保留的前缀。比如,system.users保存着数据库的用户信息,system.namespaces集合保存着所有数据库集合的信息。
IV、用户创建的集合名不能含有保留字符$。
子集合:组织集合的一种惯例是使用"."字符分开的按命名空间划分的子集合。例如,带有博客功能的应用可能包含的两个集合blog.posts和blog.authors。这样可以很清晰的表述posts和authors是博客应用的一部分,具体blog集合是否存在那无关紧要,即blog集合和其子集合没有任何关系。在MongoDB中推荐使用子集合来组织数据。
3、数据库:由多个集合组成,一个MongoDB实例可以承载多个数据库,它们之间可视为完全独立。每个数据库都有独立的权限控制,即便在磁盘上,它们存放的文件也是不同的。数据库名可以是满足以下条件的任意UTF-8字符串:
a、不能为空字符串("")。
b、不能含有‘’(空格),.(点),$,/,\和\0(空字符)。
c、应全部小写。
d、最多64字节。
数据库名最终会变成文件系统中的文件,所以才会受到以上条件的限制。有些数据库名是保留的,可以直接访问。比如,拥有所有权限的admin,该数据库中的用户会自动继承所有数据库的权限。local数据库用于存储仅限于本地单台服务器的任意集合,这个数据库永远不会被复制。config数据库用于保存分片的相关信息,当Mongo使用分片设置时会用到该数据库。
命名空间:数据库名+集合名,长度不能超过121字节,实际使用中应该小于100字节。
4、MongoDB Shell:MongoDB shell是MongoDB自带的一个JavaScript shell,可以从命令行与MongoDB实例交互。通过它可以执行管理操作,检查运行实例等,MongoDB shell即可作为JavaScript解释器,也可作为MongoDB的客户端。
4.1 运行shell。启动MongoDB实例mongod,打开另一个命令行窗口,运行mongo.exe,出现以下界面即运行成功。
注意:开启的时候,shell默认连到MongoDB服务器的test数据库,并将这个数据库连接赋值给全局变量db。这个变量是通过shell访问MongoDB的主要入口点。(shell的基本操作会在以后用到时介绍)。
二、数据类型
MongoDB支持将多种数据类型作为文档中的值。MongoDB的文档扩展自JSON,概念上和JavaScript的对象类似。MongoDB在保留JSON基本键/值对特性的基础上,添加了其他的数据类型。
1、基本数据类型
a、null,用于表示空值或不存在的字段,比如,{“x”:null}。
b、布尔,含有'true'和'false'两个值,比如,{“x”:true}。
c、32位整数,在Mongo Shell中不能使用,因为JavaScript仅支持64位浮点数,所以32为整数会被自动转换。
d、64位整数,在Mongo Shell中不支持,shell会使用一个特殊的内嵌文档来显示64位整数。
e、64位浮点数,shell中的数字都是这种类型。{“x”:3.14}和{"x":3}都是浮点数。
f、字符串,UTF-8字符串都可表示为字符串类型的数据。
g、符号,shell不支持此类型,shell会将数据库里的符号类型转换为字符串。
h、对象id,对象id是文档的12字节的唯一ID,比如,{“x”:ObjectId()}。
i、日期,存储的是从标准纪元开始的毫秒数,不存储时区,比如,{“x”:new Date()}
j、正则表达式,文档中可以包含正则表达式,采用JS的正则语法:{“x”:/foobar/i}
k、代码,文档中可以包含JavaScript代码。
l、二进制数据,可以由任意字节的串组成,shell中无法使用。
m、最大值,BSON是MongoDB采用的文档存储协议,它包含一个特殊类型,表示可能的最大值。shell中无此类型。
n、最小值,BSON中包括的一个特殊类型,表示可能的最小值。shell中无此类型。
o、未定义,{“x”:undefined}。
p、数组,值的集合或列表可以表示成数组。比如,{“x”:[“a”,"b","c"]}。
q、内嵌文档,文档可以嵌入文档。比如,{“x”:{“foo”:“bar”}}。
注:MongoDB中数字默认为双精度,如果修改文档中的整数,即使保持其值原封不动,它也会经历转化为浮点数的过程,所以尽量不要在shell下覆盖整个文档。
2、_id和ObjectId,MongoDB中存储的文档必须有一个_id键。这个键的值可以是任何类型,默认为ObjectId对象。一个集合中,每个文档都有唯一的_id值,它是集合里每个文档的唯一标识。
ObjectId:ObjectId是_id的默认类型,不同的机器都能用全局唯一的同种方法方便地生成它。ObjectId使用12字节的存储空间,每个字节两位十六进制数字,是一个24位字符串。其生成方式如下:
I、前4字节是从标准纪元开始的时间戳,单位为秒,与随后的5个字节组合后,提供了秒级别的唯一性。
II、接下来的3个字节是所在主机的唯一标识符,通常是机器主机名的散列值。这样可以确保不同主机产生不同的ObjectId,从而避免冲突。
III、接下来的两字节来自产生ObjectId的进程标识符(PID),确保同一台机器上并发的多个进程产生的ObjectId是唯一的。
IV、前9字节保证同一秒钟不同机器不同进程产生的ObjectId是唯一的,后3字节是自动增加的计数器,用于确保相同进程同一秒产生的ObjectId也是不同的。同一秒钟最大允许每个进程拥有256^3(16 777 216)个不同的ObjectId。
自动生成_id:为了增强MongoDB数据库的可扩展性,一般将生成_id的工作由客户端驱动程序完成。这样可以减轻MongoDB服务器的开销,符合MongoDB的设计理念:能从服务器端转移到驱动程序来做的事,就尽量转移。因为扩展应用层要比扩展数据库层容易得多。将事务交给客户端处理,就减轻了数据库扩展的负担。同时,可以利用驱动程序提供的丰富的API。