Я работал с различными приложениями и сталкивался с этой ситуацией много раз. До сих пор я не понял, какой подход лучше.
Вот сценарий:
- У меня есть приложение на рабочем столе или в Интернете
- Мне нужно получить простые документы из базы данных. Документ содержит общие сведения и сведения об элементе, поэтому база данных:
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
. Это похоже на ненормализованную базу данных.
Теперь вопрос в том, как избежать обходов и в то же время избежать избыточных данных?