MongoDB又被称为“无模式”的数据库,它不强制要求集合的文档拥有特定的结构。不考虑应用的结构,将应用中每个对象存储在相同的集合是合法的,尽管效率上存在问题。然后优秀的应用中常见的情景是集合会包含完全相关或密切关联的文档结构。当集合中所有文档结构是都类似的,但不是完全相同称之为多态模式。
多态模式支持面向对象编程
面向对象编程中,习惯通过继承使得不同对象共享数据和行为。面向对象语言允许函数像操作父类一样操纵子类,调用在父类中定义的方法,该方法可能在子类中采用不同的实现重载过即多态性。
多态模式使得模式进化成为可能
开发数据库驱动应用时,程序员有一个需要考虑的事情就是模式进化。典型地是使用迁移脚本将数据库从一个模式升级为另一个。在应用配置在线数据前,迁移操作可能包含删除数据库并使用新的模式重新创建数据库。然而,一旦应用是在线时,模式更改需复杂的迁移脚本来实现在保存内容的同时更改格式。
关系型数据库通过 ALTER TABLE 语句来支持迁移,可使用它添加或删除列。ALTER TABLE 语句最大的缺陷在于处理大量行数据的表时会十分耗时,而且在迁移的时候应用需下线,因为ALTER TABLE需锁定数据表文档来执行迁移。
ALTER TABLE users ADD COLUMN remark VARCHAR(255)
在MongoDB中可采用类似操作更新集合中所有文档或新增字段,$set 与 ALTER TABLE一样运行很慢且会影响到应用的性能。
db.users.update({}, {$set:{remark:''}}, false, true)
MongDB也可使用更新引用来解释缺少的新字段
BSON的存储效率
MongoDB有一个主要的特点是缺乏强制模式(存储效率),RDBMS中列名和类型格式在表级定义,因此无需在行级重复该信息。对比MongoDB来说,不知道在集合级别每个文档有哪些字段,也不知道这些字段的类型,因此每个文档都需要存储字段名和类型。
特别是在文档中存储一个较小的值(整形、日期、短字符...),并使用很长的属性名时,MongoDB将造成使用比RDBMS更多地存储空间存储相同的数据。一种减轻影响的方法是在MongoDB中的文档上使用短字段名,但该方法会导致很难在Shell中直接查看数据库。
对象文档映射
MongoDB的文档对象映射(ODM, Object-Document Mapper)是一种改进存储效率的方法。
多态模式支持半结构域数据
在某些应用中希望存储半结构化的域数据。例如 商品拥有各种属性,单并不是所有的商品都有所有属性,一种对该情形建模的方法是采用面向对象的映射方法来定义所有感兴趣的商品类型。然后真实商业世界中使用该方法还有一些需要躲避的陷阱:
- 在商品条目重新分类后商品体系可能频繁改变
- 很多商品甚至在同一类型内也可能有不完整的数据
总结
MongoDB在一个集合中的所有文档无需采用特定模式,其优势:
- 更好的针对面向对象的继承和多态的映射
- 在不同模式间迁移应用时下线时间更短
- 更好的支持半结构化领域数据