[PHP, MySQL] Database uitlezen

Pagina: 1
Acties:
  • 1.886 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • extractor
  • Registratie: September 2004
  • Laatst online: 01-08 13:38
Hey kerels, ik heb zojuist een aardig stuk code gemaakt om een kleine tabel uit te lezen. Het werkt en ik ben tevreden, maar ik streef naar perfectie en ik geloof niet dat dit de beste manier is als ik een veel grotere database heb waar ook joins in voor komen of zelfs views.
Zouden jullie daarom naar mijn code kunnen kijken en kunnen zeggen hoe ik het anders / beter had kunnen doen. bedankt!

code:
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
for ($teller = 1; $teller != $index; $teller ++)
{
// Performing SQL query
$query = "SELECT Url FROM links WHERE ID = '$teller'";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$Url = mysql_fetch_array($result, MYSQL_ASSOC);
foreach ($Url as $value)
{
    $message = "<a href=\"$value\" target=\"_blank\">";
}
// Performing SQL query
$query = "SELECT Naam FROM links WHERE ID = '$teller'";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$Naam = mysql_fetch_array($result, MYSQL_ASSOC);
foreach ($Naam as $value)
{
    $message .= "$value -";
}
// Performing SQL query
$query = "SELECT Plaats FROM links WHERE ID = '$teller'";
$result = mysql_query($query) or die('Query failed: ' . mysql_error());
$Plaats = mysql_fetch_array($result, MYSQL_ASSOC);
foreach ($Plaats as $value)
{
    $message .= "$value</a><br>\n";
    print($message);
    $message = "";
}
}

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
Hey kerel.

Queries in loops: meestal geen goed idee.
Als je toch een aantal records gaat ophalen, waarom haal je ze niet in één keer op, en loop je dan door je resultset ?

Ik zie ook dat je gewoon voor ieder veld dat je wilt tonen, hetzelfde record gaat ophalen.
Waarom haal je niet met één query die 3 velden op ?

Als index 100 is, dan ga jij dus 300 queries gaan uitvoeren om 100 lijnen op je scherm te tonen. 8)7
Iets wat perfect in één query kan....

Of wacht , ik weet het ..... jij wilt die server down krijgen...

[ Voor 13% gewijzigd door whoami op 15-01-2008 22:26 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 15:06
Dit kan in één query en zonder die buitenste for- lus:

SQL:
1
SELECT Url, Naam, Plaats FROM links
De PHP code mag je zelf verzinnen. :)

Kijk bijvoorbeeld naar Example 3 van php.net: http://nl.php.net/manual/en/function.mysql-fetch-array.php

[ Voor 32% gewijzigd door Jaap-Jan op 15-01-2008 22:30 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
Fout. :P Je bent een dingetje vergeten.

Maareh, nu geef je direct de oplossing .... Denk dat de topicstarter er meer had aan gehad, als hij zelf tot dit was gekomen.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 15:06
De WHERE-clause moet 'ie nog zelf uitzoeken, maar je hebt wel gelijk, natuurlijk. :)

edit:
Helemaal stom omdat ik me normaal gesproken voorneem om mensen op weg te willen helpen :X

[ Voor 38% gewijzigd door Jaap-Jan op 15-01-2008 22:34 ]

| Last.fm | "Mr Bent liked counting. You could trust numbers, except perhaps for pi, but he was working on that in his spare time and it was bound to give in sooner or later." -Terry Pratchett


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
PHP:
1
$Url = mysql_fetch_array($result, MYSQL_ASSOC);


Losstaand van bovenste punten, PHP heeft ook een functie voor het ophalen van enkel een associatieve array:
PHP:
1
$url = mysql_fetch_assoc($query);


Verder mis ik indenting op veel plekken en zoals gezegd maak je nu ($index * 3) - 1 teveel queries ;)

Last but not least: in mijn opinie is het 'good practice' om tabelnamen en velden tussen backticks te zetten - daarmee voorkom je ongewenst gedrag bij afwijkende namen en maak je direct duidelijk wat een datakey is. Als je ze daarnaast uitschrijft en indent wordt je code ook een stuk beter leesbaar. Zoiets dus:
SQL:
1
2
3
4
SELECT  `Url`, 
        `Naam`,
        `Plaats`
FROM    `links`


Ik gruwel zelf altijd weer als ik code doorlees waarin lange queries achter elkaar gekwakt worden alsof het niets is :+

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
FragFrog schreef op dinsdag 15 januari 2008 @ 22:54:
PHP:
1
$Url = mysql_fetch_array($result, MYSQL_ASSOC);

Last but not least: in mijn opinie is het 'good practice' om tabelnamen en velden tussen backticks te zetten - daarmee voorkom je ongewenst gedrag bij afwijkende namen en maak je direct duidelijk wat een datakey is. Als je ze daarnaast uitschrijft en indent wordt je code ook een stuk beter leesbaar.
...

Ik gruwel zelf altijd weer als ik code doorlees waarin lange queries achter elkaar gekwakt worden alsof het niets is :+
Hmmm, note to self : geen code van huidig project aan fragfrog tonen.

Hier zit gewoon een query in van 4k in 3 regels opgebouwd omdat de query compleet niets speciaals doet
Wat er met de resultaten van de query gebeurd, dat is boeiend. Dat is netjes uitgeschreven en voor de query zelf staat ook 18 regels commentaar om uit te leggen wat de query doet, het is niet speciaal, alleen veel gegevens uit veel tabellen...
Resultaat is ook maar 3 non-aggregated values, alleen moet de query wel even door 20 tabellen heen lopen op 2 manieren. Alles geinnerjoined op 1 primary key value.
Data model is niet echt 100% geschreven voor deze query, maar de query gebruikt het wel weer perfect...

Acties:
  • 0 Henk 'm!

Verwijderd

FragFrog schreef op dinsdag 15 januari 2008 @ 22:54:
Losstaand van bovenste punten, PHP heeft ook een functie voor het ophalen van enkel een associatieve array:
Bovendien is 't ook nogal overkill om elke keer een foreach te gebruiken terwijl je weet dat je maar 1 record tegelijkertijd ophaalt. Sterker nog, als 'ie meerdere records per query zou krijgen zit TS met niet te parsen HTML... ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Gokje;

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$teller = 0;
$content = '';

for ($teller = 1; $teller != $index; $teller ++) {
    
    $q = mysql_query("SELECT `Url`, `Naam`, `Plaats` FROM `links` WHERE `ID` = '".$teller."'");
    $f = mysql_fetch_assoc($q);
    
    $content .= '<a href="'.$f["Url"].'" target="_blank">'.$f["Naam"].' - '.$f["Plaats"].'</a><br />\n';
}

// echo $content;

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
^^ Da's ook nog zoveel beter niet ...

Zowiezo vreemd om quotes te zetten rond een numeriek gegeven.

Ik ben trouwens benieuwd of de TS er nu aan uitgeraakt is ...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

whoami schreef op woensdag 16 januari 2008 @ 10:07:
^^ Da's ook nog zoveel beter niet ...

Zowiezo vreemd om quotes te zetten rond een numeriek gegeven.

Ik ben trouwens benieuwd of de TS er nu aan uitgeraakt is ...
Om numeriek hoeft niet idd. Maar ik doe het altijd, gewenning (maakt neit uit welk gegevenstype). Typt voor mij dus een stuk beter.

Dit is tenminste 1 loop, fetch_assoc en stuk sneller dan wat hij hier neergezet heeft.

Acties:
  • 0 Henk 'm!

  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 19-09 21:26

DataGhost

iPL dev

Wat is er mis met
code:
1
2
3
4
query
loop {
    output
}

in plaats van
code:
1
2
3
4
loop {
    query
    output
}

? Wat gebeurt er nu als jij een rij verwijdert in je database? Verder is het inderdaad niet erg nuttig voor de TS, hij kan het klakkeloos kopieren en als hij over een paar dagen een soortgelijke query moet maken snapt hij niet waarom het zo moet/werkt en komt het opnieuw vragen.

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Verwijderd schreef op woensdag 16 januari 2008 @ 10:03:
Gokje;

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
$teller = 0;
$content = '';

for ($teller = 1; $teller != $index; $teller ++) {
    
    $q = mysql_query("SELECT `Url`, `Naam`, `Plaats` FROM `links` WHERE `ID` = '".$teller."'");
    $f = mysql_fetch_assoc($q);
    
    $content .= '<a href="'.$f["Url"].'" target="_blank">'.$f["Naam"].' - '.$f["Plaats"].'</a><br />\n';
}

// echo $content;
Alsnog ga je oneindig queries uitvoeren hier, lijkt me ook niet de bedoeling ;)
Verder kan je prima doen:
PHP:
1
2
3
4
5
6
7
$resultset = mysql_query( $query );
while( $record = $resultset->mysql_fetch_object() ){
  printf( '<a href="%s" target="_blank">%s - %s</a><br>', 
    $record->url, 
    $record->naam, 
    $record->plaats );
}
Imho de meest nette en duidelijke oplossing.
offtopic:
En fetch_object schijnt performance technisch beter te zijn dan fetch_assoc of fetch_array, maar weet niet meer waar ik dat heb gelezen.
Verwijderd schreef op woensdag 16 januari 2008 @ 10:11:
[...]


Om numeriek hoeft niet idd. Maar ik doe het altijd, gewenning (maakt neit uit welk gegevenstype). Typt voor mij dus een stuk beter.
De waek-typing van php hoef je niet te misbruiken hoor ;)
Dit is tenminste 1 loop, fetch_assoc en stuk sneller dan wat hij hier neergezet heeft.
Undefined $index -> limiet nadert oneindig ;)

[ Voor 18% gewijzigd door mithras op 16-01-2008 10:16 ]


Acties:
  • 0 Henk 'm!

  • YopY
  • Registratie: September 2003
  • Laatst online: 13-07 01:14
Punt daarmee is dat MySQL dat numerieke gegeven probeert te interpreteren als een string, wat bij een strict systeem ervoor kan zorgen dat je een mooie error krijgt (zo van 'ik blief geen strings in numerieke velden), en bij een los systeem voor een overbodige type conversie zorgt.

Zelf heb ik genoeg met quotes en handmatige MySQL queries gerommeld, daar ben ik tegenwoordig wel vanaf :+. Hibernate ftw.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
Typed voor jou een stuk beter, maar het is fout.
Ben je zeker dat er in dit geval een index kan gebruikt worden bv ?

tipje: je kan het zonder loop. Maar het is ook niet de bedoeling om het voor de topicstarter volledig voor te kauwen. En wellicht heeft hij het ondertussen zelf al gevonden, maar hij laat niet van zich horen ... :P

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

Verwijderd

Hm nu weet ik weer waarom ik nu ASP / .NET programmeer :P

Oh enne; fetch_assoc is vele malen sneller dan _object.

[ Voor 34% gewijzigd door Verwijderd op 16-01-2008 10:20 ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
Eh....

Daar ga je zeker dergelijke fouten niet moeten maken ...

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 19-09 21:26

DataGhost

iPL dev

Verwijderd schreef op woensdag 16 januari 2008 @ 10:18:
Hm nu weet ik weer waarom ik nu ASP / .NET programmeer :P
Jij werkt gewoon helemaal niet met databases? Voor zover ik weet moet je gewoon een soortgelijke constructie bouwen hoor, dit 'probleem' heeft eigenlijk bar weinig met PHP te maken. In elke taal kan je de bovengenoemde hoeveelheid gepruts neerkwakken en het zal (performance-wise o.a.) hetzelfde werken.
Oh enne; fetch_assoc is vele malen sneller dan _object.
?
http://de.php.net/mysql_fetch_object
Note: Performance Speed-wise, the function is identical to mysql_fetch_array(), and almost as quick as mysql_fetch_row() (the difference is insignificant).
http://de.php.net/manual/en/function.mysql-fetch-array.php
Note: Performance An important thing to note is that using mysql_fetch_array() is not significantly slower than using mysql_fetch_row(), while it provides a significant added value.
http://de.php.net/manual/en/function.mysql-fetch-assoc.php
Note: Performance An important thing to note is that using mysql_fetch_assoc() is not significantly slower than using mysql_fetch_row(), while it provides a significant added value.

[ Voor 45% gewijzigd door DataGhost op 16-01-2008 10:24 ]


Acties:
  • 0 Henk 'm!

Verwijderd

whoami schreef op woensdag 16 januari 2008 @ 10:18:
Eh....

Daar ga je zeker dergelijke fouten niet moeten maken ...
Nou een fout is het niet, het is een werkwijze. Ik ben bij PHP4 gestopt met PHP programmeren en het is al even geleden. Maargoed als je zo graag commentaar wil geven moet je doen hoor :)

Op een andere site stond een hele discussie over de methode fetch_object/array inclusief benchmarks. Daar werd aangetoond dat fetch_array bijna 60% sneller was

[ Voor 18% gewijzigd door Verwijderd op 16-01-2008 10:26 ]


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Verwijderd schreef op woensdag 16 januari 2008 @ 10:18:
Hm nu weet ik weer waarom ik nu ASP / .NET programmeer :P
Onnodig queries binnen oneindige loops uitvoeren is ook in ASP(.NET) stupide hoor.
Verwijderd schreef op woensdag 16 januari 2008 @ 10:11:
[...]

Om numeriek hoeft niet idd. Maar ik doe het altijd, gewenning (maakt neit uit welk gegevenstype). Typt voor mij dus een stuk beter.
Ik zou me als ik jou was toch aanwennen om datatypes wat consequenter te respecteren in plaats van ervan uit te gaan dat de database jouw luiheid wel corrigeert. Ze doen het namelijk niet allemaal, en als je je dit aanwent ga je nog eens in situaties komen waar je door side-effects volstrekt onverwachte resultaten gaat krijgen, met name binnen C++ en andere talen die je toestaan implicit conversions zelf te definieren.
Dit is tenminste 1 loop, fetch_assoc en stuk sneller dan wat hij hier neergezet heeft.
En nog steeds onnoemelijk veel langzamer dan een goede oplossing zonder lineair groeiend aantal queries.

[ Voor 12% gewijzigd door curry684 op 16-01-2008 10:36 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Verwijderd schreef op woensdag 16 januari 2008 @ 10:21:
[...]

Nou een fout is het niet, het is een werkwijze. Ik ben bij PHP4 gestopt met PHP programmeren en het is al even geleden. Maargoed als je zo graag commentaar wil geven moet je doen hoor :)
Het grootste probleem van de code van TS is dat er $index queries gedaan worden terwijl een enkele query kan volstaan en dat staat totaal los van de gebruikte taal.

offtopic:
En vergeleken hoe ineffecient die methode is is de discussie over welke mysql_fetch_* functie te gebruiken totaal niet significant. Voor code style zou je eigenlijk altijd voor assoc of object moeten gaan.

{signature}


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 14:45
Verwijderd schreef op woensdag 16 januari 2008 @ 10:21:
[...]

Nou een fout is het niet, het is een werkwijze.
:X
:')

Als jij 3000 queries kan doen, en ik kan het in één query doen. Dan is jouw werkwijze fout.
Als die 3000 queries dan ook nog allemaal eens onnodige type conversions doen, of geen indexen kunnen gebruiken doordat je met quotes zit te werken, terwijl die niet nodig zijn, dan is jouw werkwijze fout.
Foute werkwijze == een fout.

'nuff said.
Op een andere site stond een hele discussie over de methode fetch_object/array inclusief benchmarks. Daar werd aangetoond dat fetch_array bijna 60% sneller was
Dit gaat hier helemaal niet over die micro-optimalisatie ...
Het gaat over een foute werkwijze. En dat is 1000x belangrijker dan een dergelijke micro-optimalisatie.

[ Voor 33% gewijzigd door whoami op 16-01-2008 10:40 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
whoami schreef op woensdag 16 januari 2008 @ 10:38:
Dit gaat hier helemaal niet over die micro-optimalisatie ...
Het gaat over een foute werkwijze. En dat is 1000x belangrijker dan een dergelijke micro-optimalisatie.
fetch_assoc noem ik niet per definitie een slechtere werkwijze dan fetch_object hoor. Met objecten werken is leuk, maar als je bijvoorbeeld een key met een punt erin hebt (om maar een zijweg in te slaan) ontkom je niet aan arrays.

Natuurlijk, dat kun je omzeilen door SELECT AS te gebruiken of door een array met nieuwe namen mee te geven aan fetch_object, maar als je dat soort hacks moet uitvoeren kun je in mijn opinie nog beter gewoon fetch_assoc pakken :)

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

Verwijderd

Aangezien in PHP (en dan vooral 4, in 5 valt het mee) arrays verkapte objecten zijn en andersom is het inderdaad vaak het meest praktisch om gewoon fetch_array te gebruiken. Komt ook nog een bij dat fetch_array ongeveer de beste performance geeft en de functies die een betere performance hebben dat maar marginaal hebben.

Ook al is het dus offtopic: Gewoon lekker fetch_array gebruiken, dat biedt een goede performance en een hoop functionaliteit.

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

FragFrog schreef op woensdag 16 januari 2008 @ 12:16:
[...]

fetch_assoc noem ik niet per definitie een slechtere werkwijze dan fetch_object hoor. Met objecten werken is leuk, maar als je bijvoorbeeld een key met een punt erin hebt (om maar een zijweg in te slaan) ontkom je niet aan arrays.

Natuurlijk, dat kun je omzeilen door SELECT AS te gebruiken of door een array met nieuwe namen mee te geven aan fetch_object, maar als je dat soort hacks moet uitvoeren kun je in mijn opinie nog beter gewoon fetch_assoc pakken :)
offtopic:
psssst hij had het over 3000 queries ipv 1 als foute werkwijze, hij zegt juist dat welke fetch-methode je gebruikt een niet boeiende micro-optimalisatie is tov de echte fout

[ Voor 7% gewijzigd door curry684 op 16-01-2008 12:26 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
curry684 schreef op woensdag 16 januari 2008 @ 12:25:
offtopic:
psssst hij had het over 3000 queries ipv 1 als foute werkwijze, hij zegt juist dat welke fetch-methode je gebruikt een niet boeiende micro-optimalisatie is tov de echte fout
offtopic:
8)7 ik ging er vanuit dat zijn comment sloeg op de quote erboven over dat fetch_object langzamer was dan fetch_assoc

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • extractor
  • Registratie: September 2004
  • Laatst online: 01-08 13:38
Haha wat een hoop reacties op mn topic, ik zal ze eens doorlezen en een kijken of ik er verder mee kom! bedankt kerels!

Acties:
  • 0 Henk 'm!

  • extractor
  • Registratie: September 2004
  • Laatst online: 01-08 13:38
Zo ik heb heb en hij was achteraf een stuk makkelijker dan ik dacht, ik heb het met fetch_array gedaan.

code:
1
2
3
4
5
6
7
// Performing SQL query
$query = mysql_query("SELECT Url, Naam, Plaats FROM links");

while ($row = mysql_fetch_array($query, MYSQL_NUM)) 
{
    printf("<a href=\" %s \" target=\"_blank\"> %s - %s </a><br>\n", $row["0"], $row["1"], $row["2"]);
}


bedankt voor de reply's!

Acties:
  • 0 Henk 'm!

  • Koppensneller
  • Registratie: April 2002
  • Laatst online: 16:17

Koppensneller

winterrrrrr

Nu alleen nog de

PHP:
1
$row["1"]


vervangen door:

PHP:
1
$row[1]


en je bent klaar ;)

[ Voor 31% gewijzigd door Koppensneller op 16-01-2008 13:50 ]


Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

Choeso jei :)

Kleine kanttekeningen:
- In het href-attribuut hoor je geen spaties om de URL te zetten, die genereer je er nu wel in.
- Als je toch alleen indexed values wil hebben kun je net zo goed mysql_fetch_row pakken, die geeft dezelfde output als MYSQL_NUM meegeven en is wat intuitiever.
- Ipv $row['0'] zou ik $row[0] opvragen: je bespaart je een volstrekt onnodige conversie, voorkomt toekomstige problemen met named fields, en traint jezelf vast in typesafety voor als je ooit nog eens in een echte programmeertaal gaat werken.

edit:
en omdat ik zo veel typ ben ik weer traag

[ Voor 14% gewijzigd door curry684 op 16-01-2008 13:52 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
curry684 schreef op woensdag 16 januari 2008 @ 13:50:
en traint jezelf vast in typesafety voor als je ooit nog eens in een echte programmeertaal gaat werken.
offtopic:
Of bij de introductie van php6 of php7 je er ineens wel op moet letten, desnoods om onnodige notices te voorkomen :)

Acties:
  • 0 Henk 'm!

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 06-09 00:37

curry684

left part of the evil twins

offtopic:
Als PHP6 strong typed wordt is het toch al bijna een echte programmeertaal? :+

Professionele website nodig?

Pagina: 1