perl – 如何实现不涉及加载到内存的对象持久性?

我有一个
Graph对象(这是在Perl中),我计算了它的
transitive closure(即用于解决
all-pairs shortest paths问题).

从这个对象,我对计算感兴趣:

>来自任何顶点的最短路径u – >诉
>所有顶点的距离矩阵.
>一般可达性问题.
>一般图形特征(密度等).

该图有大约2000个顶点,因此计算传递闭包(使用Floyd-Warshall的算法)需要几个小时.目前我只是缓存序列化对象(使用Storable,所以它已经非常有效).

我的问题是,反序列化这个对象仍然需要相当长的时间(一分钟左右),并消耗大约4GB的RAM.这对我的申请来说是不可接受的.

因此,我一直在考虑如何设计数据库模式以将此对象保持为“展开”形式.换句话说,预先计算所有对最短路径,并以适当的方式存储它们.然后,也许使用存储过程来检索必要的信息.

我的另一个问题是,我没有数据库设计的经验,也没有关于实现上述内容的线索,因此我的帖子.我也想听听其他我可能无视的解决方案.谢谢!

最佳答案 首先,听起来你需要两个实体:顶点和边缘,也许还有几个表格用于结果.我建议一个存储节点到节点信息的表.如果A可从Y到达,则关系将获得可达属性.所以这里

Vertex:
    any coordinates (x,y,...)
    name: string
    any attributes of a vertex*

Association: 
    association_id: ID
    association_type: string

VertexInAssociation:
    vertex: (constrained to Vertex)
    association: (constrained to association)

AssociationAttributes:
    association_id: ID (constrained to association)
    attribute_name: string
    attribute_value: variable -- possibly string

*您可能还希望将顶点属性存储在表中,具体取决于它们的复杂程度.

我添加Association的复杂性的原因是边缘不被认为是方向性的,它简化了查询以将两个顶点都视为一组顶点“connected-by-edge-x”的成员

因此,边缘仅仅是边缘类型的关联,其具有距离属性.路径是路径类型的关联,它可能具有跳跃属性.

可能还有其他更优化的模式,但这个模式在概念上是纯粹的 – 即使它没有使“边缘”的第一类概念成为第一类实体.

要创建最小边缘,您需要执行以下操作:

begin transaction
select associd = max(association_id) + 1 from Association
insert into Association ( association_id, association_type ) 
    values( associd, 'edge' )
insert 
    into VertexInAssociation( association_id, vertex_id )
          select associd, ? -- $vertex->[0]->{id}
    UNION select associd, ? -- $vertex->[1]->{id}
insert into AssociationAttributes ( association_id, association_name, association_value )
          select associd, 'length', 1 
    UNION select associd, 'distance', ? -- $edge->{distance}

commit

您可能还希望创建各种类型的关联类型.这样“边缘”关联自动被计为“可达”关联.否则,您可能还想在其中插入UNION select associd,reachable,’true’.

>然后,您可以查询两个顶点的可到达关联的并集,并将它们作为可到达的关联转储到另一个节点(如果它们不存在)并将现有长度属性值1转储到length属性中.

但是,您可能想要所有这些的ORM,并且只是在Perl中操作它.

my $v1 = Vertex->new( 'V', x => 23, y => 89, red => 'hike!' );
my $e  = Edge->new( $v1, $v2 ); # perhaps Edge knows how to calculate distance.
点赞