[PHP/MySQL] gejoinde tabellen individueel uitlezen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Keiichi
  • Registratie: Juni 2005
  • Laatst online: 15-09 20:20
Ik heb een stuk PHP code welke classes heeft die overeenkomen met gelijkgenaamde tabellen in een MySQL database. Elk van deze heeft een set functie die aan de hand van een primaire sleutel z'n gegevens uit de bijhorende tabel haalt en z'n object attributen mee vult. (Overigens met mysql_fetch_object met de klassenaam)

In het geval dat ik een foreignkey heb, maak ik dus een corresponderend Object als attribute aan en laadt ie met z'n primaire sleutel.

Werkt zover perfect, maar ik krijg hierdoor gelijk massa's met queries, terwijl MySQL gewoon beschikt over JOIN.

Bij een gejoinde query heb je te maken met dat allen kolomnamen van alle tabellen bij elkaar worden gezet waardoor er geen onderscheid meer gemaakt kan worden tussen de verschillende tabellen. Ik heb bv nu X keer de kolomnaam `id`.

Is er een mogelijkheid om het resultaat, zonder gebruik te maken van kolomaliasses, uit elkaar te halen?

Solar @ Dongen: http://solar.searchy.net/ - Penpal International: http://ppi.searchy.net/


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 10:22

MueR

Admin Tweakers Discord

is niet lief

Nee. Daarom is het ook aan te raden nooit al je PKs 'id' te noemen, of 'title' in 38 tabellen gebruiken.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
MueR schreef op maandag 02 november 2009 @ 13:09:
Nee. Daarom is het ook aan te raden nooit al je PKs 'id' te noemen, of 'title' in 38 tabellen gebruiken.
Nee daarom is het ook aan te raden om gewoon aliassen te gebruiken. Ik zie het probleem van overal id gebruiken niet.

Ook ga je IMHO niet een andere naam aan een veld geven omdat je ergens anders al 'title' gebruikt hebt.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Woy schreef op maandag 02 november 2009 @ 13:18:
[...]

Nee daarom is het ook aan te raden om gewoon aliassen te gebruiken. Ik zie het probleem van overal id gebruiken niet.
  • Je hebt geen idee waar je het nu echt over hebt als je het over een 'id' hebt.
  • Dingen als natural joins en using zijn (bijna) volledig nutteloos geworden.
  • Het is niet meer terugzoekbaar met simpelweg zoeken in code.
  • Het kost zeer weinig moeite om een betere naam te gebruiken (tablenameId), terwijl er geen duidelijk voordeel is van 'id'.
Woy schreef op maandag 02 november 2009 @ 13:18:
Ook ga je IMHO niet een andere naam aan een veld geven omdat je ergens anders al 'title' gebruikt hebt.
'title' of 'name' is ook al zo lekker omschrijvend. Persoonlijk heb ik een voorkeur aan een design waarin iedere kolomnaam maar 1x voorkomt.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • b19a
  • Registratie: September 2002
  • Niet online
Grappig, hier heb ik gister net een blog-entry over geschreven: http://www.boukehaarsma.n...m-with-mysql_field_table/.

Kort antwoord: het is gewoon mogelijk, maar het is niet helemaal triviaal. Wat heb je nodig? mysql_field_table en mysql_field_name. Door deze eenmaal over alle kolommen te laten itereren kun je een tablename.fieldname-lijst opbouwen, en aan de hand daarvan je records extracten.

Kort samengevat, hier een lapje code:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$result = mysql_query("SELECT * FROM `post` JOIN `user` ON (`post`.`userId` = `user`.`id`)");

$columns = array();
for($i = 0; $i < mysql_num_fields($result); $i++) {
    $columns[] = array(
        mysql_field_table($result, $i),
        mysql_field_name($result, $i));
}

// Result:
// [["post","id"],
//  ["post","userId"],
//  ["post","message"],
//  ["user","id"],
//  ["user","name"]]

$rows = array();
while($row = mysql_fetch_row($result)) {
    foreach($row as $i => $value) {
        $row[$columns[$i][0]][$columns[$i][1]] = $value;
        unset($row[$i]);
    }
    $rows[] = $row;
}

// Result:
// [{   "post":{"id":"1","userId":"1","message":"This is Bouke's message"},
//  "user":{"id":"1","name":"Bouke"}},
//  {   "post":{"id":"2","userId":"2","message":"This is Tim's message"},
//  "user":{"id":"2","name":"Tim"}}]

[ Voor 7% gewijzigd door b19a op 02-11-2009 13:43 . Reden: toelichting erbij ]


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
pedorus schreef op maandag 02 november 2009 @ 13:26:
[...]
• Je hebt geen idee waar je het nu echt over hebt als je het over een 'id' hebt.
Wel je hebt het over een Identifier, waar ID een afkorting voor is. Perfecte omschrijving voor een veld dat een record identificeert IMHO.
• Dingen als natural joins en using zijn (bijna) volledig nutteloos geworden.
Hier volg ik je even niet
Het is niet meer terugzoekbaar met simpelweg zoeken in code.
Nee want je kunt natuurlijk ook niet zoeken op de tabelnaam? De veldnaam zal immers nooit voorkomen zonder dat dat in combinatie is met de tabelnaam
• Het kost zeer weinig moeite om een betere naam te gebruiken (tablenameId), terwijl er geen duidelijk voordeel is van 'id'.
Dat iets weinig moeite kost om het te doen is natuurlijk niet echt een argument. Het kost ook weinig moeite op alle id's 'id' te noemen.
'title' of 'name' is ook al zo lekker omschrijvend. Persoonlijk heb ik een voorkeur aan een design waarin iedere kolomnaam maar 1x voorkomt.
Persoonlijk heb ik de voorkeur aan een design waar dingen gewoon genoemd zijn naar wat het moet voorstellen. Als je een tabel NieuwsArtikel hebt vind ik titel best een omschrijvende naam. Het kan natuurlijk dat Entiteiten overeenkomende eigenschappen hebben, terwijl ze niet direct aan elkaar gerelateerd zijn.

offtopic:
Overigens gebruik ik zelf wel altijd TabelNaamId, echter zie ik het probleem in id als veldnaam gebruiken niet zo

[ Voor 4% gewijzigd door Woy op 02-11-2009 13:41 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Woy schreef op maandag 02 november 2009 @ 13:35:
Wel je hebt het over een Identifier, waar ID een afkorting voor is. Perfecte omschrijving voor een veld dat een record identificeert IMHO.
Maar in iedere view is een alias dan al snel gewenst, want dan is het onduidelijk.
Hier volg ik je even niet
In mijn gewenste design kun je bij 2 tabellen altijd hetvolgende doen:
SQL:
1
select * from a natural join b

Als iedere tabel zijn eigen 'id' heeft, gaat dit nooit lukken. Zelfde voor using.
Nee want je kunt natuurlijk ook niet zoeken op de tabelnaam? De veldnaam zal immers nooit voorkomen zonder dat dat in combinatie is met de tabelnaam
Hoe weet je uit welke tabellen een query/view/mapping zijn gegevens haalt?
Dat iets weinig moeite kost om het te doen is natuurlijk niet echt een argument. Het kost ook weinig moeite op alle id's 'id' te noemen.
Ik vraag naar voordelen ten opzichte van het andere design.
Persoonlijk heb ik de voorkeur aan een design waar dingen gewoon genoemd zijn naar wat het moet voorstellen. Als je een tabel NieuwsArtikel hebt vind ik titel best een omschrijvende naam. Het kan natuurlijk dat Entiteiten overeenkomende eigenschappen hebben, terwijl ze niet direct aan elkaar gerelateerd zijn.
Het heeft ook te maken met het ondersteunen van natural joins, het minder nodig zijn van aliassen en opzoekbare en omschrijvende namen. Ik zal dus liever ProductName en SupplierName hebben, dan 2x Name.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
pedorus schreef op maandag 02 november 2009 @ 13:49:
[...]
Maar in iedere view is een alias dan al snel gewenst, want dan is het onduidelijk.
Een view moet er inderdaad voor zorgen dat de naam in die context logisch is. Als ik in een tabel Product een veld Naam heb zitten dan is in die context perfect duidelijk wat het veld inhoud.

Als je in een view 2 tabellen samenvoegt, creëer je een nieuwe context, en zal je dus moeten zorgen dat de namen in die context omschrijvend genoeg zijn.

Als je een view maakt waar je Product regels samenvoegt tot een resulterende regel, zul je ook iets met je naamgeving moeten doen.
In mijn gewenste design kun je bij 2 tabellen altijd hetvolgende doen:
SQL:
1
select * from a natural join b

Als iedere tabel zijn eigen 'id' heeft, gaat dit nooit lukken. Zelfde voor using.
Ik doe mijn joins sowieso liever gewoon expliciet. Stel dat ik een Persoon heb, die geef ik dan bijvoorbeeld ook velden FatherId en MotherId, dus dan heb je het hele 'probleem' ook al als je die wilt joinen.
Hoe weet je uit welke tabellen een query/view/mapping zijn gegevens haalt?
Het interesseert me helemaal niet uit welke tabel een view zijn data haalt. De view moet gewoon een naamgeving aanhouden die in die context beschrijvend is.
Ik vraag naar voordelen ten opzichte van het andere design.
Je gaf het anders als argument voor het feit dat je tableNameId moet gebruiken in plaats van Id, en dan is: "Het kost niet veel werk" niet echt een argument natuurlijk!
Het heeft ook te maken met het ondersteunen van natural joins, het minder nodig zijn van aliassen en opzoekbare en omschrijvende namen. Ik zal dus liever ProductName en SupplierName hebben, dan 2x Name.
Dus ga je alle velden prefixen met de tabelnaam? Dat lijkt me ook niet echt fijn!

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Woy schreef op maandag 02 november 2009 @ 14:02:
Ik doe mijn joins sowieso liever gewoon expliciet. Stel dat ik een Persoon heb, die geef ik dan bijvoorbeeld ook velden FatherId en MotherId, dus dan heb je het hele 'probleem' ook al als je die wilt joinen.
Altijd was ook wat overdreven, ik bedoelde bijna altijd. :p Bij self-joins zoals hier gaat dat nooit lukken natuurlijk. Daarnaast heb je situaties zoals meerdere rollen binnen een project, waarbij het ook niet zal lukken. Feit is natuurlijk dat 'natural join' en 'using' niet voor niets zijn verzonnen, en dat ze met 'id' als naam zelden werken.
Het interesseert me helemaal niet uit welke tabel een view zijn data haalt. De view moet gewoon een naamgeving aanhouden die in die context beschrijvend is.
Maar het is wel mooi als over de context van een heel systeem steeds dezelfde naam voor hetzelfde gegeven gebruikt wordt.
Dus ga je alle velden prefixen met de tabelnaam? Dat lijkt me ook niet echt fijn!
Nee, zeker niet! Alleen in situaties waar problemen te verwachten zijn. Iets als BookISBN is natuurlijk onzin.

Verder is dit draadje natuurlijk een schitterend voorbeeld. Hoewel de geposte oplossing vast gaat werken, en er met mysqli/pdo vast ook oplossingen zijn, zit de bron van het probleem wat mij betreft al in het design. :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
pedorus schreef op maandag 02 november 2009 @ 14:32:
[...]
Feit is natuurlijk dat 'natural join' en 'using' niet voor niets zijn verzonnen, en dat ze met 'id' als naam zelden werken.
Ik gebruik die syntax eigenlijk nooit, expliciete joins uitschrijven is IMHO veel duidelijker. Verder zou een een RDBMS gewoon de join kunnen doen aan de hand van de PK/FK definitie die er voor de 2 tabellen is. Die definitie geeft namelijk exact aan wat de relatie tussen tabellen is, en dan ben je niet afhankelijk van je naamgeving.
Maar het is wel mooi als over de context van een heel systeem steeds dezelfde naam voor hetzelfde gegeven gebruikt wordt.
Daar zie ik het grote voordeel niet zo van. Het enige voordeel is dat het je wat type-werk scheelt.
Nee, zeker niet! Alleen in situaties waar problemen te verwachten zijn. Iets als BookISBN is natuurlijk onzin.
Maar bij bijna alle velden zou het wel voor kunnen komen. Ik vind het niet erg consequent om voor de ene helft van je velden wel een prefix te geven, en voor de andere velden niet.
Verder is dit draadje natuurlijk een schitterend voorbeeld. Hoewel de geposte oplossing vast gaat werken, en er met mysqli/pdo vast ook oplossingen zijn, zit de bron van het probleem wat mij betreft al in het design. :)
Ik ken de betreffende library niet, maar ik zou het eerder op een design probleem van die library schuiven.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Wellicht een beetje een spuit11-reactie maareh...: je specificeerd toch gewoon _altijd_ zelf de aliassen? Ik zie het hele probleem niet. Ik weet dat sowieso Zend_Db en Doctrine frameworks dat op die manier doen, anders is het toch logisch dat je niet weet welke je precies terug gaat krijgen.

Waarom je ISBN ineens zou prefixen met de tablename zou ik ook niet weten, als je een ISBN nummer hebt weet je toch automatisch dat t over n boek gaat :?

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Woy schreef op maandag 02 november 2009 @ 15:24:
[...]

Ik gebruik die syntax eigenlijk nooit, expliciete joins uitschrijven is IMHO veel duidelijker.
Het gaat er vooral om of je snel even iets kan testen met een SQL-query zonder te hoeven uitschrijven.
Verder zou een een RDBMS gewoon de join kunnen doen aan de hand van de PK/FK definitie die er voor de 2 tabellen is. Die definitie geeft namelijk exact aan wat de relatie tussen tabellen is, en dan ben je niet afhankelijk van je naamgeving.
Een natural join retourneert hetgeen waarop gejoined is als 1 kolom (per naam). In jouw systeem krijg je 2 kolommen met hetzelfde, of moet je ook dat probleem op zien te lossen (of negeren). Daarnaast is een natural join en using een daadwerkelijk al bestaand iets dat gedefinieerd is in de standaard.
Maar bij bijna alle velden zou het wel voor kunnen komen. Ik vind het niet erg consequent om voor de ene helft van je velden wel een prefix te geven, en voor de andere velden niet.
In de praktijk valt dit wel mee.
Ik ken de betreffende library niet, maar ik zou het eerder op een design probleem van die library schuiven.
Het lijkt me weinig constructief als oplossing om alle databases en libraries waarbij dit niet lekker werkt de schuld te geven. ;)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten

Pagina: 1