我使用过各种应用程序并多次遇到这种情况。直到现在我还没有弄清楚什么是最好的方法。
这是场景:
- 我有一个桌面或网络应用程序
- 我需要从数据库中检索简单的文档。该文档具有一般详细信息和项目详细信息,因此数据库:
GeneralDetails
桌子:
| DocumentID | DateCreated | Owner |
| 1 | 07/07/07 | Naruto |
| 2 | 08/08/08 | Goku |
| 3 | 09/09/09 | Taguro |
ItemDetails
桌子
| DocumentID | Item | Quantity |
| 1 | Marbles | 20 |
| 1 | Cards | 56 |
| 2 | Yo-yo | 1 |
| 2 | Chess board | 3 |
| 2 | GI Joe | 12 |
| 3 | Rubber Duck | 1 |
如您所见,这些表具有一对多的关系。现在,为了检索所有文档及其各自的项目,我总是执行以下两种操作之一:
方法 1 - 多次往返(伪代码):
Documents = GetFromDB("select DocumentID, Owner " +
"from GeneralDetails")
For Each Document in Documents
{
Display(Document["CreatedBy"])
DocumentItems = GetFromDB("select Item, Quantity " +
"from ItemDetails " +
"where DocumentID = " + Document["DocumentID"] + "")
For Each DocumentItem in DocumentItems
{
Display(DocumentItem["Item"] + " " + DocumentItem["Quantity"])
}
}
方法 2 - 很多不相关的数据(伪代码):
DocumentsAndItems = GetFromDB("select g.DocumentID, g.Owner, i.Item, i.Quantity " +
"from GeneralDetails as g " +
"inner join ItemDetails as i " +
"on g.DocumentID = i.DocumentID")
//Display...
我在大学的时候使用第一种方法做桌面应用,性能还不错,所以我意识到还可以。
直到有一天,我看到一篇文章“让网络更快”,它说多次往返数据库是不好的;所以从那以后我就使用了第二种方法。
在第二种方法中,我通过使用内部连接同时检索第一个和第二个表来避免往返,但它会产生不必要或冗余的数据。查看结果集。
| DocumentID | Owner | Item | Quantity |
| 1 | Naruto | Marbles | 20 |
| 1 | Naruto | Cards | 56 |
| 2 | Goku | Yo-yo | 1 |
| 2 | Goku | Chess board | 3 |
| 2 | Goku | GI Joe | 12 |
| 3 | Taguro | Rubber Duck | 1 |
结果集有冗余DocumentID
和Owner
。它看起来像一个非规范化的数据库。
现在,问题是,我如何避免往返,同时避免冗余数据?