Weer eens aan het spelen met PHP en MySQL. Ik ben al jaren bezig aan een eenvoudig content management system (nee, niet jaren aan een stuk maar af en toe nieuwe features toevoegen
). Nu heb ik al een tijd m'n zinnen gezet op het systeem dat tweakers.net gebruikt om z'n nieuwsberichten weer te geven. Onderaan elke nieuwspost staan 2 links; eentje naar het volgende nieuwsbericht, en eentje naar het vorige. Dat maakt het navigeren meer eenvoudiger omdat je niet telkens terug naar de index pagina moet gaan.
Nu heb ik eens liggen denken om dit zelf ook te implementeren, maar dan liefst wel effeciënt (ik ben op oplossingen gekomen die elke SQL-guru zou doen groen uitslaan
).
Het simpelste is natuurlijk in de query waar je het nieuwsbericht uit de database ophaalt uitbreiden via de WHERE zodat ie ook -1 en +1 kijkt. Bijvoorbeeld (vereenvoudigde query):
SELECT * FROM news WHERE news.id >= ($id - 1) AND news.id <= ($id + 1)
Waarbij $id het op te halen artikel is. Maar dit schept wat problemen. Je krijgt nu 3 rijen terug. Maar de database bevat ook verschillende categorieën van nieuws en wat als je het laatste of eerste bericht bekijkt? Dan krijg je geen drie rijen. Of wat wanneer een bericht gedelete werd uit de database?
Even voor de duidelijkheid een zeer simplistisch model van de nieuwsdatabase schetsen. Veld titel is natuurlijk de titel van het nieuwsbericht en bericht de inhoud. Veld categorie duidt aan tot welke categorie het bericht behoort, bijvoorbeeld zoals op Tweakers.net softwarenieuws, hardwarenieuws, gamesnieuws,... Maar bij mijn CMS worden ze in aparte lijsten weergegeven. Er horen dus geen softwarelinks bij hardwarenieuws te komen.
Stel dat ik het bericht met $id = 7 wil ophalen. Rij 7 behoort tot categorie 2. Dat betekent dat enkel volgende/vorige links naar berichten uit categorie 2 mogen weergegeven worden. Een hogere id dan 7 in categorie 2 is er niet, dus de volgende link vervalt al. Een lagere is er wel, namelijk id 6. Nu valt die toevallig 1 id lager (ivm het eerder vernoemde -1/+1), maar dat is lang niet altijd zo. Wat bijvoorbeeld als je id = 5 wil ophalen?
Het model dat ik probeer te schetsen zou nu toch verstaanbaar moeten zijn. Dus nu de vraag... Hoe giet ik dit in een MySQL query? Bestaat er een opdracht om de eerst dichtstbijzijnde rij te zoeken (ik vond niet meteen iets in de MySQL manual)? Je kunt toch moeilijk alle rijen inlezen en dan manueel de dichtstbijzijnde rijen bij de gevraagde id zoeken. Dat moet toch efficiënter kunnen?
Nu heb ik eens liggen denken om dit zelf ook te implementeren, maar dan liefst wel effeciënt (ik ben op oplossingen gekomen die elke SQL-guru zou doen groen uitslaan
Het simpelste is natuurlijk in de query waar je het nieuwsbericht uit de database ophaalt uitbreiden via de WHERE zodat ie ook -1 en +1 kijkt. Bijvoorbeeld (vereenvoudigde query):
SELECT * FROM news WHERE news.id >= ($id - 1) AND news.id <= ($id + 1)
Waarbij $id het op te halen artikel is. Maar dit schept wat problemen. Je krijgt nu 3 rijen terug. Maar de database bevat ook verschillende categorieën van nieuws en wat als je het laatste of eerste bericht bekijkt? Dan krijg je geen drie rijen. Of wat wanneer een bericht gedelete werd uit de database?
Even voor de duidelijkheid een zeer simplistisch model van de nieuwsdatabase schetsen. Veld titel is natuurlijk de titel van het nieuwsbericht en bericht de inhoud. Veld categorie duidt aan tot welke categorie het bericht behoort, bijvoorbeeld zoals op Tweakers.net softwarenieuws, hardwarenieuws, gamesnieuws,... Maar bij mijn CMS worden ze in aparte lijsten weergegeven. Er horen dus geen softwarelinks bij hardwarenieuws te komen.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| SELECT * FROM news; +----+--------------+-------------------+-----------+ | id | titel | bericht | categorie | +----+--------------+-------------------+-----------+ | 1 | titel1 | bericht1 | 1 | | 2 | titel2 | bericht2 | 1 | | 3 | titel3 | bericht3 | 1 | | 4 | titel4 | bericht4 | 2 | | 5 | titel5 | bericht5 | 1 | | 6 | titel6 | bericht6 | 2 | | 7 | titel7 | bericht7 | 2 | | 8 | titel8 | bericht8 | 1 | | 9 | titel9 | bericht9 | 3 | | 10 | titel10 | bericht10 | 1 | +----+--------------+-------------------+-----------+ |
Stel dat ik het bericht met $id = 7 wil ophalen. Rij 7 behoort tot categorie 2. Dat betekent dat enkel volgende/vorige links naar berichten uit categorie 2 mogen weergegeven worden. Een hogere id dan 7 in categorie 2 is er niet, dus de volgende link vervalt al. Een lagere is er wel, namelijk id 6. Nu valt die toevallig 1 id lager (ivm het eerder vernoemde -1/+1), maar dat is lang niet altijd zo. Wat bijvoorbeeld als je id = 5 wil ophalen?
Het model dat ik probeer te schetsen zou nu toch verstaanbaar moeten zijn. Dus nu de vraag... Hoe giet ik dit in een MySQL query? Bestaat er een opdracht om de eerst dichtstbijzijnde rij te zoeken (ik vond niet meteen iets in de MySQL manual)? Je kunt toch moeilijk alle rijen inlezen en dan manueel de dichtstbijzijnde rijen bij de gevraagde id zoeken. Dat moet toch efficiënter kunnen?
A bus station is where a bus stops. A train station is where a train stops... On my desk I have a workstation.