此问题旨在与软件/平台无关。我只是在寻找通用的 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
可以看到,Book
和Author
之间是一对多的关系,之间是多对多的关系图书
和商店
。
问题一:将一位作者及其书籍(以及书籍的销售地点)加载到每行代表一个对象实例的面向对象程序中的最佳查询是什么?
问题二:将整个对象树预先加载到面向对象程序中的最佳查询是什么,其中每一行代表一个对象实例?
这两种情况在延迟加载中都很容易想象。在任何一种情况下,您都可以通过一个查询获取作者,然后一旦您需要他们的书(以及这些书在哪些商店出售),您将使用另一个查询来获取该信息。
延迟加载是执行此操作的最佳方法还是我应该在创建对象树时使用连接并解析结果(试图预先加载数据)?在这种情况下会怎样是数据库的最佳连接/目标输出以使解析尽可能简单?
据我所知,通过预先加载,我在解析数据时需要管理某种所有对象的字典或索引。实际情况是这样还是有更好的方法?
最佳答案
这是一个很难回答的问题。我之前通过编写一个查询将所有内容作为平面表返回,然后遍历结果,在最重要的列发生变化时创建对象或结构来完成此操作。我认为这比多个数据库调用更有效,因为每个调用都涉及很多开销,尽管这取决于每个大实体有多少个小实体,这可能不是最好的。
以下内容可能适用于您的问题 1 和 2。
SELECT a.id, a.name, b.id, b.name FROM authors a LEFT JOIN books b ON a.id=b.author
(伪代码,在您的程序中进行数据库调用)
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;
}
[edit] 我刚刚意识到我没有回答你问题的第二部分。根据商店数据的大小以及我打算用它做什么,我要么
在像上面一样循环遍历书籍/作者之前,将整个商店表插入我程序中的一个结构,很像上面的书籍/作者结构,但由 storeid 索引,然后每次阅读时在该结构中查找一本书记录并存储对存储表的引用
或者,如果有很多商店,
将商店连接到书籍上,并有一个额外的嵌套循环以在添加书籍的代码部分中添加商店对象。
这是一篇相关的维基百科文章:http://en.wikipedia.org/wiki/Object-relational_impedance_mismatch
希望对您有所帮助!
关于sql - 获取存储在 RDBMS 中的对象树的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6702916/