1、NoSQL的技术基础及其实践对象关系映射领域驱动的聚合设计聚合数据模型指不兼容面向对象编程语言的类型系统之间进行数据转换的技术对象模型和关系模型存在着固有差异可以在若干层次解决问题:语言库级别数据库级别Hibernate是典型的ORM框架面向对象数据库和NoSQL是数据库级别的解决方案大多数业务应用主要考虑CRUD对磁盘的读写分层提供了组织这种逻辑的方法根据目的或主题将逻辑集中起来一站式购物(“1 stop shopping”)持有持久存储的数据模型Data entities (i.e. tables)Data types (i.e. columns )Data relations ( i.e
2、. referential integrity )Data integrity ( i.e. check constraints, triggers, etc.)管理对数据模型的读写执行SQL语句或者存储过程根本上确保所支持的ACID原则技术Normalization vs. DenormalizationHorizontal and Vertical PartitioningMaterialized Views,数据模型考虑的是如何最佳存取数据随着时间的推移,可能发生变化可能服务于多个应用系统设计应该具有改变数据模型的灵活性将数据模型变化对其他层次的影响减小到最少 (i.e. 计入降低各层之
3、间的耦合度)易于找到受到数据模型变化影响的代码知道数据源的标识知道如何连接数据管理层知道如何实现CRUD运用SQL和存储过程可能有,也可能没有具体的层次通常表现为一组“数据访问对象”DAL logic通常出现在领域对象 (Domain Objects)中领域对象标识问题域的实体e.g. Customer, Order, Vendor管理临时状态调用数据访问操作强制数据验证执行业务规则定义领域中实体之间的关系Data Model != Domain Model数据模型定义数据如何存放数据模型的实际是最优地支持数据读写和完整性领域模型定义数据如何使用集成和多态扮演着重要角色领域模型和数据模型的松耦
4、合可以出尽它们各自独立的演化源于电子工程的阻抗匹配90年代,面向对象数据库风靡一时,但是随着面向对象语言的崛起,面向对象数据库反而日渐式微面向关系数据库抓住了机会,强化了在计算机软件中作为集成机制的角色,分离了应用开发人员和数据库管理员两种角色。面向对象范式基于软件工程原理,而关系范式基于数学原理 鼓励/禁止传引用 字符串差异数据类型差异 对象组装/类继承机制是OR不具备的 OR的声明式约束方式 OO通常采用保护逻辑报异常的方式,或采用面向方面方法设计结构和完整性差异 OR采用基于元组的原语操作 OO采用底层的物理访问路径相关的命令式操作操作差异 OO语言没有类似隔离性和持久性概念事务性差异对
5、象模型中类数量和关系数据库中表的数目通常是不同的public class Teacherpublic class School继承是面向对象编程语言中得自然泛型,但是RDBMS不支持这个概念HumanManWomanInheritance 实体关联通过外关键字对象关联通常是单向的部分出现在整体中部分对整体的应用并不常见Class user_main Teacher teacher;Class Teacher 字符串数据类型是典型的例子在RDBMS中字符串具有长度,尾部空格通常没有含义一般的面向对象语言字符串没有长度限制对象世界和关系世界的Date和time存在很大差异为了避免不必要的麻烦,有的
6、应用在RDBMS中使用字符串类型标识Date和Time声明和命令接口OR视数据为接口,OO视行为为接口活动和实体之间的关系OR分离了实体与行为结构与行为基于集合论的OR,基于图论的OO对象范式与关系范式ORM桥接OO和OR为应用提供面向对象的数据访问接口Value Object和Data Access Object成为主要的设计模式1.Mapping 2.Reflection, Projection and Hydration3.SQL Query Builder4.Fetching5.Caching and persistence6.Settings1.Storage Model2.Conc
7、eptual Model3.Mapping Model使用XML描述模型之间的映射关系Java Annotation是另外的形式是否需要在装载一个对象时,将其所有成员一起装载?lazy loading. Lazy loading是一种设计模式按需装载的意思只有在需要的时候才装载/初始化对象Lazy loading Levels列级别关联级别缓存动态生成查询,不需要每次重建缓存避免了对数据源的重复调用查询优化处理环形引用处理层叠(cascade)更新批量更新和删除软件平台是否开源DoctrinePHP是RedBeanPHPPHP是Dapper.NET是ECO.NET否EntitySpaces.N
8、ET是EclipseLinkJava是HibernateJava是MyBatis/iBATIS跨平台是jOOQJava是Apache Cayenne Java是LLBLGen Pro.NET否软件平台是否开源Microsoft ADO.NET Entity Framework .NET否nHibernate.NET是ODB跨平台C+否SQLAlchemyPython是SQLObjectPython是StormPython是SubSonic.NET是TopLinkJava否SkipperPHP否WebORB Integration Server.NET, Java, PHP是DBIx:Class
9、Perl是可以通过XML文件或者Java Annotation将Java类映射到关系表支持一对多和多对多关系的映射支持自定义数据类型的映射Enum、一个属性映射到多个列支持QBE、QBA、QBL(HQL)查询支持POJO的透明持久化不将Java对象映射到关系表,而是将Java方法映射到SQL语句在应用端实现数据库中存储过程、视图和查询等机制提供一种将查询结果映射到对象树的机制来源于“领域驱动设计”它是作为一个单位进行处理的相关对象集合,特别是数据操作和一致性管理的单位使用源自操作来更新聚合,以聚合的形式与数据存储进行通信数据库可以将聚合作为复制和分片的单元/ in customers “id:
10、1,name:Martin,billingAddress:city:Chicago/ in orders “id:99,customerId:1,orderItems:productId:27,price: 32.45,productName: NoSQL Distilled,shippingAddress:city:ChicagoorderPayment:ccinfo:1000-1000-1000-1000,txnId:abelif879rft,billingAddress: city: Chicago,/ in customers customer: id: 1,name: Martin,
11、billingAddress: city: Chicago,orders: id:99,customerId:1,orderItems:productId:27,price: 32.45,productName: NoSQL Distilled,“shippingAddress”:“city”:“Chicago”,orderPayment:ccinfo:1000-1000-1000-1000,txnId:abelif879rft,billingAddress: city: Chicago,不是划分聚合边界,而是规划数据访问方式从领域角度看待数据易于将聚合数据分离在不同节点面向聚合不再支持ACI
12、D的事务大多数源自操作局限在聚合内部一般不支持跨越聚合边界的ACID事务T1 HTML into Java Objects T2 Java Objects into SQL Tables T4 Tables into Objects T3 Objects into HTML T4Objects into HTMLT5Objects to XMLT6XML to ObjectsT1HTML into Java ObjectsT2Java Objects into SQL TablesT3Tables into Objects对象到表的映射问题模式所有权(Schema-Ownership)冲突双向
13、模式(Dual-Schema)问题实体标识问题数据检索接口问题部分对象问题和装载时间悖论大多数ORM都是与RDBMS紧耦合的范式扼杀了Web应用范式的目标是让数据尽可能地小Web应用的目标是尽可能地快具有广泛用户的Web应用都没有遵循3范式的Web应用受到性能压力会快速降低到更低范式(denormalization).RESTful APIs典型地适用于与单表应用http:/ WikiMedia example - direct access to MySQL and PostgreSQL 相对于RDBMS,Key-value存储可能更适合Web应用适合复杂类型的JOIN操作不要用RDBMS实
14、现key-value存储如果数据库足够快,不要使用cacheDont shard yourself.列族存储图存储Documents in the databaseDocuments in the applicationNo object middle tierNo shredding”No reassemblySimple!XML lives in the web browser (Xforms)REST interfacesXML in the database (Native XML, Xquery)XRX Web Application ArchitectureNo translati
15、on!系统在数据装载到数据库的时候,自动决定如何索引数据不需要数据结构的先验知识不需要预先的逻辑数据建模数据模型依然存在,但是隐含在处理逻辑中更易于存储实际得到的数据,而不是我们想我们可能得到的数据“We can easily store the data that we actually get, not the data we thought we would get.不需要在插入第一条记录之前完成建模不需要数据定义语言元数据用于在数据到达时穿件索引建模编程了一个统计过程编写查询来寻找异常或者规格化数据异常制造规则数据验证通常利用一些特殊工具来实现,例如XML Schema、业务规则系统
16、Schematron 全局数据定义预先定义数据类型及其关系查询更有效可以根据数据类型、列值和关系类型约束行为优化访问用于确定如何最优存储、管理和访问特定数据类型易于Query By Example,展示可用信息类型信息之间的关系互操作适应语言和环境控制模式的改变保持应用和数据的同步一致的安全控制模式需要维护应用要保持与模式的同步应用关心数据类型缺少特殊应用所需的灵活性灵活可以将任意类型的数据持久化可以创立任意类型的关系对数据的寻找不再关心数据类型可以容忍不同的ACID和一致性易于使用和维护不需要专职的DBA新型数据出现后应用也可以工作增加新的的数据成分或者改变数据成分,不会造成混乱亿量级数据的
17、搜索可以达到次秒级的响应时间混淆(Confusion)性能问题(Performance suffers)完整性问题(Poor Integrity)含糊(Ambiguity)SCHEMA:Network CODASYL databases - DDL 1972Relational Databases - Data DictionaryObject Databases - ODMG93Most Graph DatabasesSchema-less:KSAM/ISAM/DSAM/ESAMIMS (hierarchical)Pick OS Database (hash-tables)MUMPS (hi
18、erarchical array-storage)MongoDB - a specialized JSON (and JSON-like)document store.CouchDB - a JSON document store.Key-valueDocumentColumn FamilyGraph键用于访问不透明的一团数据值可以包含任意类型的数据(images, video)Pros: scalable, simple API (put, get, delete)Cons: no way to query based on the content of the value /* Query
19、 1 */ SELECT age FROM users WHERE id = 1; /* will read 21 */ 只有两列Key/Value的表Value列没有数据类型约束接口简单Add a key-valueFor this key, give me the valueDelete a key特别快而且易于扩展 (no joins) 单词“gouge”就是“键”内容和图片就是“值”Eventuallyconsistent keyvalue storeHierarchical keyvalue storesKey-Value stores in RAMKey-Value stores
20、on diskHigh availability key-value storeOrdered keyvalue storesValues that allow simple list operations 一种特殊的Key-Value存储Key包括行标识、列族和列名保持了Key-Value存储的一般特性,而且提供了更高级的数据抽象和访问接口行和列的设计非常重要但是相对于RDBMS来说,还是容易得多Bigtable系统中的Key可以不仅有行和列ID还有其他属性,列族和时间戳列族在创建表的时候创建时间戳(Timestamps)允许存储不同版本的数据Value仅仅是一个字节序列,没有强类型保留了与
21、RDBMS类似的表结构没有针对JOIN的优化可以大量的行和列,但是行的列可以不同列族允许查询具有相同特性(组)的所有行插入新的列不需要alter table在插入时触发增加列将一组列组成列族(Column families)将一组列族组成超列(Super-Columns)允许以超列和列族进行查询相似的数据组合在一起,以提高访问速度数据存储为嵌套层次结构逻辑数据依然作为一个单元存储在一起可以查询文档中得任意元素排除了ORM的需要,易于搜索实现复杂,与SQL不兼容将一份机器可读的文档作为一组数据存储在一起使用JSON或者XML格式类似于对象存储(object stores)不需要将数据分割(No
22、shredding)为多张表文档的子树和属性可以用Xquery或者其它语言查询甚至可以包括ACID事务的支持脱离ORM,较好地支持敏捷开发一个容器包含了所有词语内容分析需要大量、复杂的算法关键词已经分解成了各个子文档成分使用倒排索引,将关键词与每个文档的每个node-id关联起来数据存储为一系列节点、关系和属性查询是图遍历数据之间的关系是关键e.g. social networks支持快速地网络搜索图太大时,可扩展性不好特殊的查询语言 (RDF使用SPARQL) 适用于数据项的关系以及关系类型非常重要的场合社会网络查询:friends of my friends推理和规则引擎模式识别适合开放链接数据公开数据的自动连接(joins)图中的每个节点和边都有一组Key/Value对,即属性