Imagine a database with two tables like this:
persons
---------
|pid|name|
| 0| Tom|
| 1|Hans|
| 2| Ken|
---------
cars
---------------
|cid|pid| car|
| 0| 1| BMW|
| 1| 1| Audi|
| 2| 2| Benz|
---------------
A 1:n relation between persons and cars.
What is the best practice to associate these in code?
Let's assume I'd like to fill this simple class:
class Person {
string name;
List<string> cars;
}
From the top of my head I could go three ways:
Way 1:
Do two queries separately and do a nested foreach to associate all cars.
Two SQL Queries:
SELECT * FROM persons;
SELECT * FROM cars;
With the simplistic pseudo code:
List<Person> personList;
foreach(row in personQuery) {
person = new Person(personQuery.name);
foreach(row in carQuery)
if(carQuery.pid == personQuery.pid)
person.AddCar(carQuery.car);
}
Way 2:
Do one query with a join and ignore duplicate information.
One SQL Query: SELECT * FROM persons JOIN cars ON persons.pid = cars.pid;
With:
List<Person> personList;
int lastID;
foreach(row in Query) {
if(Query.pid != lastID) {
person = new Person(personQuery.name);
personList.Add(person);
}
person.AddCar(Query.car);
}
Way 3:
Do one query to get all persons and then one for each person to get the associated cars.
Many SQL Queries:
SELECT * FROM persons;
SELECT * FROM cars WHERE pid = @param;
With:
List<Person> personList;
foreach(row in personQuery) {
person = new Person(personQuery.name);
carQuery = DoCarQuery(personQuery.pid);
foreach(row in carQuery)
person.AddCar(carQuery.car);
personList.Add(person);
}
In my testing it seems like the first way is the fastest, but it degrades really fast because it's a n^m approach and it gets even slower if I have multiple 1:n relations like a third table with "bikes" in the example above.
I encounter this problem regularly in my work and couldn't find a best practice only, though this could be because I couldn't word the problem accurately, because I only found matches on how to make 1:n databases in the first place :/
Aucun commentaire:
Enregistrer un commentaire