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

Perl 如何实现不涉及内存加载的对象持久性?,perl,database-design,serialization,graph,persistence,Perl,Database Design,Serialization,Graph,Persistence,我有一个对象(在Perl中),我为它计算它的值(即,用于解决问题) 从这个对象,我对计算感兴趣: 从任意顶点u->v的最短路径 所有顶点的距离矩阵 一般可达性问题 一般图形特征(密度等) 该图大约有2000个顶点,因此计算传递闭包(使用的算法)需要几个小时。目前,我只是缓存序列化对象(使用,因此已经相当有效) 我的问题是,反序列化这个对象仍然需要相当长的时间(一分钟左右),并且消耗大约4GB的RAM。这对我的申请来说是不可接受的 因此,我一直在考虑如何设计一个数据库模式,以“展开”的形式保存这个

我有一个对象(在Perl中),我为它计算它的值(即,用于解决问题)

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

  • 从任意顶点u->v的最短路径
  • 所有顶点的距离矩阵
  • 一般可达性问题
  • 一般图形特征(密度等)
  • 该图大约有2000个顶点,因此计算传递闭包(使用的算法)需要几个小时。目前,我只是缓存序列化对象(使用,因此已经相当有效)

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

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


    我的另一个问题是,我没有数据库设计的经验,也不知道如何实现上述功能,因此我发表了这篇文章。我还想听听我可能忽视的其他解决方案。谢谢

    首先,听起来您需要两个实体:顶点和边,可能还需要两个表格来获得结果。我建议使用一个存储节点到节点信息的表。如果A可以从Y访问,则关系将获得reachable属性。这就来了

    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
    
    *您可能还希望将顶点属性存储在表中,具体取决于它们的复杂程度

    我增加关联复杂性的原因是,一个边缘不被认为是有方向性的,它简化了查询,将两个顶点都考虑为一组顶点的成员“连接EdGEX”

    因此,边只是边类型的关联,具有距离属性。路径是路径类型的关联,它可能具有hops属性

    可能还有其他更优化的模式,但这一模式在概念上是纯粹的——即使它不会使“edge”的一流概念成为一流实体

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

    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转储到长度属性中
    然而,您可能需要一个用于所有这些的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.
    

    谢谢,太详细了!我需要一些时间来咀嚼它,但它看起来确实很有用。问:您使用的语法是某种伪SQL代码吗?我问这个问题是因为它看起来很轻松,但定义却很正式,我对它不熟悉。@Pedro Silva,是的,这只是一些用来设计数据模型的伪代码