获取存储在RDBMS中的对象树的最佳方法

knp*_*wrs 5 sql database object

此问题旨在与软件/平台无关.我只是在寻找通用的SQL代码.

考虑以下(非常简单的例子)表:

Table: Authors
id   | name
1    | Tyson
2    | Gordon
3    | Tony
etc

Table: Books
id   | author   | title
1    | 1        | Tyson's First Book
2    | 2        | Gordon's Book
3    | 1        | Tyson's Second Book
4    | 3        | Tony's Book
etc

Table: Stores
id   | name
1    | Books Overflow
2    | Books Exchange
etc

Table: Stores_Books
id   | store   | book
1    | 1       | 1
2    | 2       | 4
3    | 1       | 3
4    | 2       | 2

正如您所看到的,Books和Authors之间存在一对多关系,Books和Stores 之间存在多对多关系.

问题一:将一位作者及其书籍(以及销售书籍的位置)急切加载到面向对象程序中的最佳查询是什么,其中每一行代表一个对象实例?

问题二:将整个对象树急切加载到面向对象程序中的最佳查询是什么,其中每一行代表一个对象实例?

使用延迟加载很容易想象这两种情况.在任何一种情况下,您都可以通过一个查询获取作者,然后只要您需要他们的书籍(以及销售书籍的商店),您就可以使用另一个查询来获取该信息.

是否延迟加载是执行此操作的最佳方法,还是应该在创建对象树时使用连接并解析结果(尝试加载数据)?在这种情况下,为了使解析尽可能简单,数据库的最佳连接/目标输出是什么?

据我所知,在急切加载时,我需要在解析数据时管理某些所有对象的字典或索引.实际情况是这样还是有更好的方法?

rat*_*ane 3

这是一个很难回答的问题。我之前已经通过编写一个查询将所有内容作为平面表返回,然后循环遍历结果,在最重要的列发生变化时创建对象或结构来完成此操作。我认为这比多个数据库调用效果更好,因为每个调用都会涉及很多开销,尽管这取决于每个大实体有多少个较小的实体,这可能不是最好的。

以下内容可能适用于您的问题 1 和 2。

SELECT a.id, a.name, b.id, b.name FROM authors a LEFT JOIN books b ON a.id=b.author
Run Code Online (Sandbox Code Playgroud)

(伪代码,在您进行数据库调用的程序中)

while (%row=fetchrow) {
   if ($row{a.id} != currentauthor.id) {
      currentauthor.id=$row{a.id};
      currentauthor.name=$row{a.name};
      }
    currentbook=new book($row{b.id, b.name});
    push currentauthor.booklist, currentbook;
    }
Run Code Online (Sandbox Code Playgroud)

[编辑]我刚刚意识到我没有回答你问题的第二部分。根据商店数据的大小以及我打算用它做什么,我会

在如上所述循环书籍/作者之前,将整个商店表放入我的程序中的结构中,非常类似于上面的书籍/作者结构,但由 storeid 索引,然后每次阅读书籍记录时在该结构中进行查找并存储对存储表的引用

或者,如果有很多商店,

将商店连接到书籍上,并有一个额外的嵌套循环来在添加书籍的代码部分中添加商店对象。

这是相关的维基百科文章:http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch

我希望这有帮助!