图数据存储初见

 在《图数据挖掘——基本概念》一文中详细的讲了图数据的基本概念,并在图数据挖掘之图信息获取及存储》一文中描述了图的信息获取,但并无对图数据的存储进行详细的介绍,该篇将就图数据存储给你们介绍一下,若有不对之处但愿多多指出!数据库

        咱们都知道图数据主要的信息是节点、边和权重,如何存储这些信息是相当重要的,同时采用何种存储结构对图的还原影响很是大。今天将介绍两种图的存储方式:1)关系数据库存储 2)关系数据库+文本。

        1)关系数据库存储

         如上面的图,咱们知道其中有V一、V二、V三、 V四、 V五、 V6节点,同时也有7条边,并对应了各自的权重。如何使用关系数据库来存储这些信息,将在此处给你们介绍。要存储这些信息须要建立一个关系表,第一个就是节点表:用于存储节点的详细信息(节点里面包含的数据),并给节点一个惟一的编号,如一、二、三、4......。另外还要建立一个边关系表:用于存储边的详细信息,咱们知道边通常包含两个节点和权重,咱们此处称两个节点为起始节点和终止节点。如何将这些信息存储到数据库中,下面将举例说明:
节点关系表
节点编号 节点信息
1 V1
2 V2
3 V3
4 V4
5 V5
6 V6
边关系表
边编号 起始节点编号 终止节点编号 权重
1 1 3 5
2 1 5 4
3 1 6 2
4 2 3 1
5 2 5 6
6 3 1 5
7 3 2 1
8 3 4 3
9 4 3 3
10 4 6 5
11 5 1 4
12 5 2 6
13 6 1 2
14 6 4 5
         因为上面给出的图是无向图,因此两个节点之间的边的关系是相互的,如V1——>V3那么V3——>V1。因此边的关系表中有14条记录。上面列举出了节点的存储结构和边的存储结构,那么如何根据这些信息还原图的结构呢?其实要还原图,只需关注边的关系表就够了,而节点关系表只是存储节点详细信息的,而图的搜索和数据挖掘在开始时是不须要这些节点的详细信息,而是在挖掘到了有用的信息时才从关系表中获取每一个节点的详细信息。因此在进行搜索或者其余的图挖掘的时候彻底不须要知道节点详细信息,而是只要拿到每一个节点的惟一编号就好了,当须要时再根据这个编号到节点关系表中获取节点的信息,这样作能够减小图所占用的内存,由于此时每一个节点只是一个数字,而不是那些复杂的信息。废话很少说,那么如何根据边关系表获得图呢?还原图其实只需选择一个节点出发,对图进行探索就好了。如此处选择编号为1的节点(此后将以节点编号表示一个节点)对图进行探索:能够根据上面的表知道和1相连的节点有三、5和6,那么就存在1——>3,1——>5和1——>6(此时是找以1为起始节点的边),能够知道如今图的结构已经探索到了三、5和6节点,那么接下来将对三、5和6进行探索,即获取以3为起始节点、5为起始节点和6为起始节点的边,依次类推,将构造出一个图的结构。你们可能都看获得,其实上面的三、5和6都是1的邻接节点,因此能够推出:一个邻接节点将产生一条边(此处的邻接节点是和节点直接相连的节点,而且可达,如是有向边,这就要考虑方向性,反向是不可达的,因此此时不存在相互性),因此图的边能够直接更具节点的邻接节点来进行存储,这样能够简化图的还原。你们可能发现这样经过数据库来对图进行扩展是很是漫长的,若是图有上百万个节点,那么下个要经过这样的数据库来进行还原图那是很是艰苦的。下面介绍一种相对比较好的存储方式。

      2)关系数据库+文本

       此种方法就是将节点的详细信息存储到数据库中,因此还使用上面的节点关系表,而此处的边就不能存储在数据库中了,而是存储在文本中,此处就不对节点存储进行详细的介绍了。上面最后说过一个节点和其邻接节点就会构成一条边,因此此处就是经过存储邻接节点来对边进行存储了。咱们是将每一个节点的邻接节点经过数组写到文本中,可知一个节点的邻接节点不止一个,因此每一个节点的邻接节点是存储在文本中的某一块区域,因此此处须要引入偏移量的概念,此处每一个节点对应了一个偏移量,这个偏移量是作什么用的呢?就是指出这个节点的邻接节点信息是存储在文本的那个位置开始。同时能够知道一个节点的邻接节点个数是和该节点的度有关的,例如上面的1节点有3个度,那么1将有3个邻接节点,因此将产生3条边,这是一个重要的概念,由于度的大小和一个节点的邻接节点个数相同,同时也影响该节点在存储邻接节点文本所占据的大小。说了这么多确定会晕的,下面仍是举个例子说明吧:
邻接节点文本
位置 邻接节点
0 3
1 5
2 6
3 3
4 5
5 1
6 2
7 4
8 3
9 6
10 1
11 2
12 1
13 4
节点度文本
节点编号
1 3
2 2
3 3
4 2
5 2
6 2
   
邻接节点偏移量
节点编号 偏移量
1 0
2 3
3 5
4 8
5 10
6 12
          此处能够看出,1的邻接节点是存储在邻接节点文本的0位置到2的位置,2的邻接节点是存储在3位置到4的位置.....其余的节点也能够以此退出,其实在文本中存储是以数组存储的,并无上面那样的结构,如邻接节点文本:[3,5,6,3,5,1,2,4,3,6,1,2,1,4],在文本中每一个数字一行,而偏移量就是某个节点的邻接节点存储位置的起始位置,而长度为该节点的度的大小,一样节点的度和偏移量也是这样存储的,也是每一个数组一行,同时行数和节点的编号要对应,如1节点是第一行,2节点是第二行....由于这些值是和节点一一对应的。在咱们的程序中实际上是将这些信息经过IO读到数组中,如咱们定义一个adjancent[]数组用于存放邻接节点的,adjancentoffset[]存储偏移量的,degree[]是存储节点度的。如1节点的度是degree[0],它的邻接节点偏移量是为:adjancentoffset[0],那么1节点的邻接节点是存储在adjancent[adjancentoffset[0]]到adjancent[adjancentoffset[0]+degree[0]-1]中,那么就会产生相应的边,那么边的编号就是adjancentoffset[0]~adjancentoffset[0]+degree[0]-1,能够看到边的编号和邻接节点的存储位置是对应的,由于一个邻接节点对应了一条边,上面已经讲过,此处就不在赘述。咱们就能够将这些数组存放在程序中,并利用这些数组还原图结构,例如:咱们仍是以1节点开始扩展图:1的邻接节点有三、5和6,此时就扩展了三个节点,在经过这三个节点扩展它们各自的邻接节点,依此类推,边还原了图的结构,该种方法,避免了大量的数据库的访问,而是经过把图存储在文本中,并一次性的读入到内存中,并经过迭代还原图结构。但这种操做容易产生几种缺陷,第1、图的信息更新不方便,应为向图中添加了一些节点,那么就要从新生成这些文本,第2、这些图的信息所有存储在内存中,使得图的大小收到内存的限制。我作试验的时候,存储2百万个节点2百多万条边的图占内存20多M。因此多余图的节点个数不怎么更改,图的节点个数不不亿量级的能够采起这样的方式存储。关于该种方法的使用详细见 《一种图存储结构【看了以后你会对图的结构有新的认识》
       此文到此已差很少结束,但愿若有什么不对的地方洗完指出!欢迎评论该文!
       谢谢浏览!此文完!
相关文章
相关标签/搜索