MongoDB实战第二版笔记(5)第四章笔记

MongoDB实战第二版笔记(5)第四章

  1、数据库Schema设计是基于数据库特性、数据属性和应用系统选择最好的数据表示形式的过程。RDBMS 只需要遵守数据库设计范式,用以确保通用查询和数据一致性。

  2、使用数据库系统建模需要思考的问题:

  • 应用访问模式是什么?需分解需求,落实scheme设计和选择应采用的数据库。
    1. 应用程序特征要求scheme严格遵守数据建模原则
    2. 决定理想数据模型需考虑:读/写比率?查询简单?查询一个key还是更复杂的key?是否需聚合查询?数据量多少?
  • 数据的基本单位是什么?MongoDB数据基本单位是BSON,RDBMS是行列的表。
  • 数据库功能是什么?
    1. RDBMS有ad hoc 查询以及连接通常写入SQL,而简单键值存储通过key获取数据。MongoDB允许ad hoc查询但不支持join连接查询。
    2. RDBMS使用SQL进行复杂更新,事务可含多个更新并支持原子性和回滚。MongoDB不支持事务,但支持另外一个原子更新操作,可以更新复杂结构稳定的数据库。使用键值库,每次更新一个值意味完全替换一个值。
  • 如何记录生成好的唯一ID或主键?选择key的策略会影响访问和存储数据。

  3、最好的scheme是深入了解使用的数据库、了解应用系统需求及具有丰富经验之后的产物。需要试验和迭代【应用伸缩和性能考虑变化】。

  4、推荐为文档窗户slug字段构建有意义的URL,通常作为唯一索引,用以加速查询且确保唯一。可在_id字段存储用作主键。

  5、数据库是集合和索引的命名空间和物理分组

  6、MongoDB不显式创建数据库,而是第一次写入数据时创建数据库。ruby代码示例。

   connection = MongoDB::Client::new(['127.0.0.1:27017'],:database=>'garden')
    db = connection.database

类似shell中 use garden

此时数据库不存在,还没有创建在磁盘上。

  7、向集合写入数据才创建数据库文件。ruby示例。

    products = db['products']
    products.insert_one({:name=>"Extra Large Wheelbarrow"})

  调用insert_one,驱动告诉MongoDB将商品信息插入garden.products集合,若集合不存在则创建,而且会在磁盘上创建garden数据库

  8、删除集合中所有数据 products.find({}).delete_many,只会清空集合不删集合。

  9、删除集合 products.drop,ruby中删除garden数据库。 db.drop。mongoDB的shell则 use garden然后 db.dropDatabase()

  10、MongoDB创建数据库会在磁盘上分配一系列数据库文件集合,包括所有集合、索引和其他元数据。数据库文件存储在启动mongod时depath参数指定的目录文件夹,不指定则在默认文件夹下存储。

  11、数据库配置

  • mongod.lock,存储服务器进程ID。
  • .ns文件,名字为集合或索引元数据名,后缀表示命名空间,组织形式hash表。数据库中每个集合和索引的元数据都有自己命名空间文件。默认情况是16MB,大约存储26000个数据。【数据库中索引和集合数目综合不能超过26000】,如果超过,启动Mongod则需要 -nssize 修改
  • 创建命名空间文件,MongoDB为集合和索引在文件里分配空间,以0开始递增至结束。MongoDB会以预分配空间方式确保足够多数据可以持续存储在文件中【可能很大】,当用户查询和更新数据,这些操作会在临近区域执行而非跨磁盘。
  • 随着持续添加数据到数据库,MongoDB会持续分配更多数据文件,新文件会是前一个的两倍,直到2GB的上限,后续都是2GB。【导致实际分配空间比使用空间大得多】
  • 使用 db.stats() 查询使用空间和分配空间

  12、集合是结构或概念上相似文档的容器。

  13、MongoDB shell的集合创建命令 db.createCollection("users") ,可指定预分配字节大小【但并不必要】 db.createCollection("users",{size:20000})

  14、集合名字可能包含数字、字母或圆点字符,最好由字母或数字开头。集合名字通过命名空间区分,包含所属数据库名字。圆点符号有时可用作虚拟命名空间。

  15、集合重命名,如示例: db.products.renameCollection("store_products")

  16、盖子集合,指有限的集合,最初为高性能日志场景设计,有固定大小。一旦达到最大上限,后续插入会覆盖最先插入的文档数据。

  17、MongoDB允许为盖子集合指定最大稳定数量的max参数,这允许对存储文档的总数进行细粒度控制。大小配置具有优先权。

    db.createCollection("user.actions",{capped:true,size:16384,max:100})

  18、盖子集合不允许正常集合操作,比如删除,增加文档大小。最初是为日志设计。

  19、TTL(time-to-live)集合,允许在特定的时间后废弃文档数据,通过特殊索引实现。

  实例为在time_field字段上创建索引,该字段定期检查时间戳,用与当前时间值比较,若是差距大于expireAfterSeconds设置(例子设置1小时),文档会自动删除。

    db.reviews.createIndex({time_field:1},{expireAfterSeconds:3600})

  TCL只会比较索引值和当前值差别。

  TTL索引限制:1)不能在_id字段建立,或者已经建立索引的字段建立;2)不能在盖子集合使用TCL索引,因其不支持删除单文档。3)可以在索引字段里有一组时间戳,但不能组合TTL所以。

  20、系统集合。MongoDB有两个特殊集合,system.namespaces和system.indexes。前者用以查询当前数据库定义的所有命名空间【find命令】。后者存储当前数据库定义的所有索引。

  21、MongoDB复制功能使用盖子集合,该功能保证多个mongod数据库之间的数据库同步。每个主从复制集在特殊的盖子集合oplog.rs里记录了所有的写操作日志。从节点从这个集合里依次读取数据,应用到自己数据库中。

  22、所有文档发送给MongoDB前都被序列化为BSON格式,然后从BSON反序列化。驱动库会处理底层数据类型转换。绝大部分驱动都提供BSON序列化的简单接口,当读/写文档的时候会自动完成。

  23、MongoDB为集合分配特定空间,一定要用于存储元数据。正常的集合(非盖子集合)更新文档会导致空间增长,需要移动性的地址,并留出空白区,这导致数据大小和MongoDB占用的磁盘空间之间有差别。

  24、StringIO帮助类反序列化BSON,但不能序列化任意哈希数据结构。要做到无错序列化,key名字必须有效,且每个值必须可被转换为BSON类型。有效key名字最大255B长度的字符串组成。字符串可以由任意合法的ASCII字符组成。但不能由$开始,不能包含圆点,不能包含null字节。

  25、字符串必须UTF-8,如果是旧编码格式字符串导入MongoDB则需要先转换成UTF-8,再插入,或者直接把文档存储为BSON二进制类型。

  26、BSON的三种类型:double,int,long。BSON可以编码任意IEEE浮点值以及任意8B长度的有符号整数。

  • ruby和python序列化整数,驱动会自动确定编码为int或long int。
  • shell中,保存数据类型为整数类型,需要指定类型,NumberLong()或NumberInt(),默认情况下是Number,等价于IEEE 754 Double

  27、$type操作符查询BSON类型。每个类型有整数标识,从1开始。

  28、BSON类型缺少小数位支持,例如存储货币数据值,必须整数类型,单位为分。

  29、BSON的实际类型用来存储临时值,从Unix纪元计时开始值使用64b整数的毫秒值表示,负数表示之前的时间。在JavaScript创建日期,月份从0开始,即new Data(2011,5,11)表示2011年6月11日。使用Ruby驱动存储类似数据,BSON序列化会期望越高UTC格式的Ruby Time。因而不能用日期类型表示时间区间,BSON时间不能编码此时间数据。

  30、可以自定义虚拟类型实现存储带有时区的时间。

    {
        time_with_zone:{
            time:new Date(),
            zone:"EST"
        }
    }

Ruby编写的MongoDB对象映射器允许我们通过定义to_mongo和from_mongo方法来处理自定义数据类型。

  31、BSON文档限制16MB,原因:

  (1)阻止开发者创建无意义的数据类型。

  (2)与性能相关。服务器端查询大文档需要发送客户端之前把文档拷贝到缓存里,该工作昂贵,特别是客户端不需要整个文档时。

  32、MongoDB嵌套深度(即文档里包含新文档)最大限制是100。

  33、Ruby大量插入例子

    docs = [# define an array of document
    	{:username=>'kbanker'},
    	{:username=>'pbakkum'},
    	{:username=>'sverch'}
    ]
    @col = @db['test_bulk_insert']
    @ids = @col.insert_many(docs) # pass the entire array to insert
    put "Here are the ids from the bulk insert:#{@ids.inspect}"

  大量插入返回对象的ID数组而不是单个ID。

  • 只需要一个连接可以插入大量数据而不需要大量独立地来回往返
  • 插入100万个文档,必须分割多个大量插入的文档组(批量插入大小16MB)
发布了189 篇原创文章 · 获赞 675 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/YuYunTan/article/details/85316892