1.前言
近几年,随着WEB的发展,大家意识到传统关系数据库的不足,于是各种适用于WEB应用的非关系型数据就应运而生了.如 Cassandra, MongoDB等.也就是所谓的NOSQL数据库.
而另一方面程序员期望的面向对象型数据库,却还远不成熟,迟迟未能出现一件像样的产品,原因各种各样,但最大的问题可能是难度太大,其实面向对象型数据库差不多伴随面向对象语言的发展,在很早就已经出现了.但它有太多的晦涩和局限之处,有兴趣大家可以去研究一下,但是它在第二轮数据库大战中输给了关系数据库。
传统的关系型数据库作为数据存储的首选工具地位在短期内无法撼动。以这种数据库为基础发展起来的工具非常之多,历史也非常久远。而且关系数据库也尝试加入一些面向对象的特性,如音频、图像等新数据类型、自定义数据类型以及重载运算符等等。而Postgresql在面向对象方面更进一步,加入了如继承等特性, 一般称之为ORDBMS。
在RDBMS的使用者也从另一面方尝试解决RDBMS与应用之间的一些模式映射匹配问题,近几年出现了ORM技术,为RDBMS与面向对象语言之间减少了一些隔壑,虽然并没有从根本上解决问题,但作了一些很好的尝试,也获得了广泛的应用.但使用ORM技术,通过 Hibernate(或其他 ORM 工具)访问RDBMS,映射问题也无法彻底解决,它们只会转移到配置文件。而且,有以下问题。
1. 如果您想要创建一个分层良好的继承模型,将它映射到表或一组表无疑会是失败之举。若用违背常规形式的方式来换取查询的性能,就会将
DBA 与开发人员在某种程度上对立起来。面向对象中的继承也不能过于频繁的使用,而且不易于使用.例如你不可能让所有的实体类继承于同一个类.
2. 关系不作为实体出现, 实体之间的关系简化为依赖这一种.无法为实体之间的关系建立一个分层良好的继承模型,而有时关系很重要,如网络故障分析中网络对象之间的关系显得至关重要.
与此同时,还出现了一些专用某个领域的数据库如CMDB和GeoDatabase。
像CMDB,它将实体之间的关系提高到了与实体同等的地位,并提供了一个图查询的方法。可惜它并没有作为一个通用的数据库出现,它甚至不是真的作为一个数据库存在,而只是对CMDB用户来说像一个数据库而已.
我在网络中找到一种与CMDB很类似的数据库,名为GraphDatabase,其中的代表是Neo4j,可惜它不是免费的。而只能用于java语言。更为重要的是它们都是自已实现了一个存储系统,不能与RDBMS共存,可实际情况中,RDBMS是主流我们根本不可能抛弃它,因此我想基于RDBMS开发一个GraphDatabase数据库。它作为一个RMDBS的前端运行。
2.设想
我设想的GraphDatabase数据库并不想做成万能的,仅仅处理已有的RDBMS+ORM遇到的一些问题,在此我对这个数据库做了一些设想:
1. 很好的支持继承,让面向对象语言更方便的映射。但它并不是面向对象数据库。
2. 将关系提升至与实体同等的地位,并提供完整的图查询操作。
3. 鉴于RDBMS的垄断地位,它应该能与RDBMS良好的集成,基于它开发,也就是说本数据库的数据模型能够简单地映射到RDBMS,它们之间有一个简单的映射机制。
4. 数据库中的信息主要通过如下3个基本的构建块表示:
a) 条目(Item, 又叫做vertex)——从概念上来说,这类似于对象实例,拥有唯一的ID,并包含0个或多个以上的属性组(attributeGroup)。
b) 关系(relationship,又叫做edge)——它连接了两个Item,此外还具有方向和类型(RelationshipType),它实际上是条目(Item)的一个子类。
c) 属性组(attributeGroup) ——它是一组 key/Value对的集合。Item与Relationship都有零到多个attributeGroup。
鉴于第3个需求,我们必须基于RDBMS 上来开发,做一个数据库的前端,它可以嵌入在其他应用程序中,也可以独立运行。
此外,我们还应加上一些额外的可选功能,如
1. 数据的版本信息
2. 数据的状态管理
3. 数据的变更记录
4. 数据的基线功能
5. 自动的全文搜索
3.需求
在做这个数据库前我们还是先确定一下上述的第2种情况主要有那些需求.
3.1数据的定义
本数据库是用条目(item)、关系(relationship)和属性组(attributeGroup)三个概念来组织数据的,用户可以按自已的需求定义这三种对象,将数据库的数据看成一个有属性的有向图,如下
条目(item)就是图中的节点, 关系(relationship)就是图中的边。节点和边都具有属性,它们用属性组(attributeGroup)来组织。这三个对象的UML类图如下
所有用户自定义的条目(item)、关系(relationship)和属性组(attributeGroup)都必须从它们继承。
3.1.1条目(item)
一个条目(item)代表一个对象实例(如计算机,应用软件,或其它),
1. 每一个条目(item)将至少有一个唯一的Id,并充当一个Key
2. 为一个条目(item)指定一个Id.后,它可能用在任何需要Id的场合
3. 一个条目(item)具有0个或多个属性组(attributeGroup)。注意它自己不能直接包含属性。
3.1.2关系(relationship)
一个关系(relationship)表示源条目(item)与目标条目(item)之间的连接。如一个软件“运行(runs)”在一个操作系统上、一个操作系统“安装(installed)”在一个计算机上、一个故障(incident)记录“影响(affects)”一个计算机、以及一个服务使用另一个服务。关系(relationship)有下列特征:
1.
一个关系(relationship)严格的连接两个条目(item),一个是源,一个是目标,并提供关于这个关系(relationship)的信息。
2. 一个关系(relationship)是一个条目(item)的子类,并具有一个条目(item)的所有特征。如每个关系(relationship)都将有一个唯一的ID,并作为key。
3.
一个关系是有方向的,但本系统并没有为这个方向赋予什么特殊的意义。但删除是依赖于方向的,具体请见删除条目。
4.
一个关系(relationship)具有0个或多个属性组(attributeGroup)。注意它自己不能直接包含属性。
3.1.3属性组(attributeGroup)
属性组(attributeGroup)表示一个含有描述条目(item)或关系的属性(注意这里的属性是类似于数据库表中的字段,而不是像C#语言中的属性)的集合。属性组(attributeGroup)有下列特征:
1. 一个属性组(attributeGroup)必须关联于一个条目(item)或关系(relationship)
2. 一个属性组(attributeGroup)可能含有用于标识条目(item)或关系(relationship)的属性,或它可能含有描述条目(item)或关系(relationship)的属性
3. 不同类型的几条属性组(attributeGroup)可能关联相同的条目(item)或关系(relationship)
4. 一个属性组(attributeGroup)可能含有多个属性,也有可以不含属性,这时它充当一个标记。
一个属性组(attributeGroup)类似于SQL视图中的一行。它是一个属性的投影。相同的属性可能出现在同一个条目(item)或关系的多个属性组(attributeGroup)中。属性组(attributeGroup)可能没有属性,这种情况下它用于充当一个标记。
每个属性组(attributeGroup)可能有下列描述属性组(attributeGroup)自身的元属性
1. 有一个Id在它所关联的条目(item)或关系(relationship)的范围内中唯一的,并充当key(如果条目(item)或关系(relationship)只有一个记录时是可选地)
2. 记录的日期/时间是最后修改时间(可选的)
为什么提供属性组(attributeGroup)这样一个东西,而不是直接让条目(item)或关系(relationship)拥有属性呢?
因为真实世界中一个对象从不同角度来看它可能有不同的属性,如一个计算机,从网管员的角度看,它有主机名,IP地址,MAC址址,CPU型号,MEM大小, 硬盘容量等属性,而对财务部门的角度来看,它有订单号,单价,购买日期,使用年限,维护人等信息,
如果我们提供属性组(attributeGroup)这个概念后,用户在建立模型时可以从不同角度对实物建模,一个条目(item)可以有一到多个属性组(attributeGroup),每个属性组(attributeGroup)针对一个或多个使用者.
3.1.4继承
以上三个对象都像类一样可以继承,用户可以用它们来对自已的领域建模,它们继承的行为如下:
属性组(attributeGroup)的继承非常类似于普通的类,当一个属性组(attributeGroup)继承另一个属性组(attributeGroup)时,就具有它的所有属性,但它没有方法。属性不能重载。
条目(item)的继承则表示: 当一个条目(item)继承另一个条目(item)时,就具有它的所有属性组(attributeGroup).此外它还有二个特殊的地方:
1. 当一个条目(item)继承另一个条目(item)时,子条目(item)中有一个属性组(attributeGroup), 该属性组在子条目(item)重复申明了, 或该属性组(attributeGroup)也有一个父属性组(attributeGroup),它的父属性组(attributeGroup)已经存在于父条目(item)中,那么子条目(item)中的该属性组(attributeGroup)覆盖父条目(item)中的父属性组(attributeGroup),
2. 当出现上述情况,同时子条目(item)的约束与父条目(item)不一致时,需要注意, 父条目(item)中的约束必须比子条目(item)中的约束更严格.
这里说约束是指条目与属性组的约束.
关系(relationship)是条目(item)的一个子类,因此它的继承行为与条目(item)的继承行为完全一致。
3.1.5数据类型
Integer 通过指定范围来确定是int8, int16, int32,int64
Numeric 用户指定精度
Money 专用于存储货币类型的数据
String, 用户指定长度来确是是 char, varchar还是text
date/timestamp/duration
boolean
ipAddress ip地址,包括ipv4和ipv6
physicalAddress MAC地址
GUID类型
XML 数据
数组
在这里我就不详细说了,将会在概要设计中说明.
3.1.6约束
在描述约束之前我们说明一下约束更严格的含义: 约束a比约束b更严格,意味着假如一个实例满足约束a,那么该实例一定满足约束b,反之不一定成立。
约束分为三种:一种是针对属性的值约束,一种是条目与属性组的约束,一种是针对条目与条目的关系约束。
3.1.6.1属性的值约束
它主要是针对单个值的限定,它是我从xml的限定学过来的
限定 |
描述 |
|
|