SQLAlchemy和MySQL的多链接列表



我希望使用MySQL和SQLAlchemy(0.7)在SQL表中有多个链表。所有列表的第一个节点都是父节点为0,子节点为0。id表示列表,而不是独立元素。该元素由PK 识别

有了一些省略的语法(与问题无关),它应该看起来像这样:

id(INT, PK)
content (TEXT)
parent(INT, FK(id), PK)
child(INT, FK(id), PK)

由于该表有多个链表,如何从数据库中返回整个列表?我选择了一个特定的ID,父项为0?

例如:

SELECT * FROM ... WHERE id = 3 AND parent = 0   

假设在同一个表中存储了多个链表,我假设您将这些链表的HEAD和/或TAIL存储在其他一些表中。很少有想法:

1)保留链接列表:从数据查询的角度来看,第一个大的改进(也在评论中提出)是为同一列表中的所有节点提供一些公共标识符(让我们称之为ListID)。这里有几个选项:

  • 如果每个列表仅从一个对象(数据行)引用[我甚至会提出这样的问题:"列表是否属于单个对象?],那么这个ListID可以只是持有者对象的(主要)标识符,ForeignKey在顶部,以确保数据完整性。在这种情况下,查询所有列表非常简单。事实上,您可以定义relationship并像my_object.my_list_items一样对其进行导航
  • 如果列表由多个对象使用/引用,则可以创建另一个表,该表将仅由一列ListID (PK)组成,并且每个节点/项都将再次具有ForeignKey或类似的内容
  • 否则,可以在两个查询/SQL语句中加载大列表:
    1. 按ID查询HEAD/TAIL
    2. 根据接收到的HEAD/TAIL的ListID查询整个列表
      事实上,这可以用一个查询来完成,比如下面的查询(单查询示例),从IO的角度来看效率更高,但分两个步骤完成的好处是可以立即引用HEAD(或TAIL)节点

单个查询示例:

# single-query using join (not tested)
Head = alias(Node)
qry = session.query(Node).join(Head, Node.ListID == Head.ListID).filter(Head.ID == head_node_id)

在任何情况下,为了遍历链表,您都必须根据其ID获取HEAD/TAIL,然后像往常一样遍历
注意:在这里,我不确定SA是否会识别出引用对象已经加载到会话中,或者会为每个引用对象发出其他SQL语句,这将无法实现批量加载的目的


2)用Ordering List扩展名替换链表:
请阅读订购单文档。Ordering List的实现可能足够好,您可以使用它来代替链接列表

相关内容

  • 没有找到相关文章

最新更新