[SQL] Join pakt eerste ipv laatste

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Hallo,
Ik probeer een klein actieve-topics lijstje te maken. Daarvoor had ik deze query gemaakt:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
            SELECT
                r.tid, t.title, t.status, r.time,
                u.username
            FROM
                forum r
            JOIN
                forum t
            ON
                (t.id=r.tid)
            JOIN
                members u
            ON
                (u.id=r.uid)
            GROUP BY
                t.id
            ORDER BY
                r.time
            DESC
            LIMIT
                :limit

Ik heb dus één tabel voor alle forumberichten, genaamd forum. Door middel van een check (id=tid > post_id = topic_id) kijk ik of het geselecteerde bericht een topic is of niet (dus als ik een topic wil WHERE id=tid).

forum r > hiermee haal ik de laatste post uit de database.
forum t > dit is het topic waar de reactie bij hoort.

Nu werkt de query op zich redelijk goed. Alleen heb ik een probleem:
Als er reacties op een topic zijn dan pakt hij de time en username van de EERSTE reactie in plaats van de LAATSTE reactie.
Ik heb verschillende dingen geprobeerd maar ik kom er even niet meer uit.

Kan iemand mij misschien helpen? :)

[ Voor 6% gewijzigd door Saven op 01-02-2009 17:21 ]


Acties:
  • 0 Henk 'm!

  • P-Storm
  • Registratie: September 2006
  • Laatst online: 21:10
Misschien een simpele sort, zoals ORDER BY DESC/ASC?

SQL:
1
2
3
4
SELECT supplier_city
FROM suppliers
WHERE supplier_name = 'IBM'
ORDER BY supplier_city DESC;

Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Ik gebruik al ORDER BY ;) :P

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Ik begrijp dat hij ze nu groepeert op topic_id, maar hij pakt dus zegmaar de eerste ipv de laatste.
Als ik DISTINCT(r.tid) opvraag, dan krijg ik alsnog dubbele resultaten in het lijstje. En dat moet niet :P

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Lees die link eens helemaal, inclusief de opmerking over mysql. In 't kort, verdere uitleg komt er niet want dan moet je maar echt lezen: Order by gebeurt pas na het groeperen. Tijdens het groeperen moet er dus random data gekozen worden als je het groeperen niet goed specificeert.

{signature}


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Saven schreef op zondag 01 februari 2009 @ 17:57:
[...]

Ik begrijp dat hij ze nu groepeert op topic_id, maar hij pakt dus zegmaar de eerste ipv de laatste.
En exact waar in die query vertel je de database dat hij de laatste moet hebben en niet de eerste?

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
De query is ongeldig en had nooit mogen worden uitgevoerd door de database. Dat dit toch gebeurt, zegt veel over de "kwaliteit" van de door jou gekozen database...

Ga de boel zo configureren dat foute/onmogelijke queries met een dikke foutmelding worden afgeschoten. Een database die onzin uit zijn duim zuigt, heb je niks aan.

http://wiki.phpfreakz.nl/Werken_met_MySQL#Configuratie

Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
curry684 schreef op zondag 01 februari 2009 @ 18:26:
[...]

En exact waar in die query vertel je de database dat hij de laatste moet hebben en niet de eerste?
Ja goede vraag, ik weet dus niet hoe dat moet :$

Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
cariolive23 schreef op zondag 01 februari 2009 @ 18:45:
De query is ongeldig en had nooit mogen worden uitgevoerd door de database. Dat dit toch gebeurt, zegt veel over de "kwaliteit" van de door jou gekozen database...

Ga de boel zo configureren dat foute/onmogelijke queries met een dikke foutmelding worden afgeschoten. Een database die onzin uit zijn duim zuigt, heb je niks aan.

http://wiki.phpfreakz.nl/Werken_met_MySQL#Configuratie
Hoewel group-by misschien toch uitgevoerd wordt ondanks dat het een niet 'perfecte' query is zou ik mijn MySQL database iig nooit afstellen naar aanlijding van dit document (excuses als je het zelf hebt geschreven) het aantal keren dat er staat 'waarom dit wel kan weet ik niet maar doe het maar uit, want in situatie x kan het onwenselijk zijn' weet ik niet, maar het zijn er aanzienlijk veel.

Verder hebben de meeste mensen zelf geen invloed op de configuratie van hun mysql database, en als ze dat wel hebben vraag ik toch heel lief om er alleen aan te zitten als je toch echt op een veel hoger niveau bezig bent met databases.

We hebben het hier gewoon over een group-by/order-by foutje laten we het daar over hebben :) .

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Dankje Roy :)

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

roy-t schreef op zondag 01 februari 2009 @ 19:25:
[...]

We hebben het hier gewoon over een group-by/order-by foutje laten we het daar over hebben :) .
Het probleem is tweeledig: allereerst snapt Saven niet hoe GROUP BY werkt, en het is niet zozeer een foutje, want wat ie wil kan gewoon niet met GROUP BY. Als ie GROUP BY had gesnapt alvorens het te gebruiken had ie dit probleem niet gehad.

Het tweede deel van het probleem is dus dat ie er niet achter komt dat dit niet kan omdat z'n database hem er niet voor op z'n falie geeft dat ie iets onmogelijks probeert. Binnen die context is cariolive's post alleszins relevant en ontopic, omdat het namelijk het hele probleem had kunnen voorkomen in een vroeger stadium (met de kanttekening dat ik het evenmin eens ben met veel suggesties uit het gelinkte documentje).

Het probleem in kwestie is alleen op te lossen door subqueries of denormalisering, waarbij de eerste preferent is voor zuiverheid en de tweede voor performance op systemen van enige grootte. Bij het onderzoeken van optie 2 zal Saven overigens ook nog tegen "probleem drie" aanlopen - namelijk dat je een database alleen kunt denormaliseren als hij origineel goed ontworpen en genormaliseerd is, en dat is ie pertinent niet als topics en berichten in dezelfde tabel staan.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Waarom is het fout om alle forumberichten in één tabel te doen? Een stuk makkelijker imo

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Uhm ja alle forumberichten in 1 tabel is wel handig, maar tenzij je je topicstart hier wel heel erg cryptisch hebt geschreven begrijp ik eruit dat je de topics er ook als zodanig inzet. Dan ben je 2 verschillende entiteiten in 1 tabel aan het stoppen, en da's altijd A Bad Ideatm.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Ja ik ben geen database expert :P maar daar vallen inderdaad ook topics onder.
Maar ik heb nu dan de volgende query gemaakt omdat het zoals ik het wou nooit ging lukken. Dus probeer ik het volgende, alleen nu wilt de site niet meer laden (laad een uur lang ofzo doet niks). Dus er zit een foutje in ofzo maar ik kom er niet meer uit ;(
SQL:
1
2
3
4
5
6
7
8
9
10
11
            SELECT
                f.id, f.title, f.status
            FROM
                forum f
            WHERE
                f.time = (SELECT r.time FROM forum as r WHERE r.tid=f.id ORDER BY r.time DESC LIMIT 1)
            ORDER BY
                f.id
            DESC
            LIMIT
                :limit

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Hoeveel rows zitten er in die tabel? :X Hebben we het hier over het forum op je eigen site met 98676 berichten?

Op wat schoonheidsfoutjes klopt die query namelijk wel zo'n beetje, en dan loop je dus aan tegen wat ik bedoelde met "de tweede voor performance op systemen van enige grootte".

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
er zijn bijna 100.000 rows in de tabel inderdaad
maar waarom zou dit niet werken dan? lijkt me een beetje sterk dat dit wel zou werken dan op een tabel met 100 rows en niet op 100.000 rows :P

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18-09 17:06

gorgi_19

Kruimeltjes zijn weer op :9

curry684 schreef op zondag 01 februari 2009 @ 21:15:
Hoeveel rows zitten er in die tabel? :X Hebben we het hier over het forum op je eigen site met 98676 berichten?

Op wat schoonheidsfoutjes klopt die query namelijk wel zo'n beetje, en dan loop je dus aan tegen wat ik bedoelde met "de tweede voor performance op systemen van enige grootte".
En / of wat indexen die ontbreken :P

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Saven schreef op zondag 01 februari 2009 @ 21:19:
er zijn bijna 100.000 rows in de tabel inderdaad
maar waarom zou dit niet werken dan? lijkt me een beetje sterk dat dit wel zou werken dan op een tabel met 100 rows en niet op 100.000 rows :P
Kijk eens goed wat die query doet.... als je indexen niet kloppen (dank gorgsel ;) ) ben je in het eerste geval 100*100 = 10.000 rows aan het scannen, in het tweede geval 100.000 * 100.000 = 10 miljard rows aan het scannen. Gezien je lockup van een uur vermoed ik dat je indexen niet kloppen.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Ik neem aan dat ik dan een index op time moet uitvoeren.
Ben der mee bezig, maar ik vrees :P IE is met phpMyAdmin al een minuut aan het laden ofzo

edit:
ja hoor
De webpagina kan niet worden weergegeven

Meest waarschijnlijke oorzaken:
Uw computer is niet met internet verbonden.
Er zijn problemen op de website opgetreden.
U hebt het adres mogelijk verkeerd getypt.
edit: nu kan ik ook niet meer via phpmyadmin in die tabel komen :') omfg
de connectie kan de website nog wel maken, alleen ik kan er niet in via PMA 8)7

[ Voor 61% gewijzigd door Saven op 01-02-2009 21:37 ]


Acties:
  • 0 Henk 'm!

  • roy-t
  • Registratie: Oktober 2004
  • Laatst online: 08-09 11:33
Het aantal records klinkt niet heel schrikwekkend, vziw heeft oa phpbb iig alle berichten in 1 tabel (geen apparte tabel per topic, wat nogal lastig zou worden op een gegeven moment :) )

Het is wel lastig dat de topicstarts ook in dezelfde tabel staan, hoewel deze door deze query dan juist wel goed meegenomen zouden worden. Misschien moet je het in 2 stappen doen. Eerst maar is uitzoeken welke berichten er als laatste zijn gemaakt en daarna daar appart de topics bij zoeken en die groeperen.

Helaas ben ik absoluut geen database expert.

Verder als PMA niet meer werkt kun je MySQL Administrator proberen vanaf je desktop. (downloaden vanaf de mysql website). Die kan er dan vast wel weer in komen. Probeer in dat zelfde pakket ook de MySQL Query Browser waar je queries op je database kunt uitvoeren met wat uitgebebreidere mogelijkheden om te zien wat er gebeurt.

Edit: sorry curry684, ik zie nu na nog is goed lezen dat je eigenlijk het zelfde hebt gepost, volgens mij zijn wij het eens hier :) . En mja MySQL die group by toch door laat gaan was geen vreselijk probleem in dit geval, een bericht hoort maar bij 1 topic, dus de enige fout die hier gemaakt was, was dat als er in 1 topic de laaste minuut meerdere berichten geplaatst werden mogelijk het topic meerdere keren voor kwam in het resultaat. (of dat wenselijk is of niet ligt natuurlijk aan de situatie :) )

[ Voor 22% gewijzigd door roy-t op 01-02-2009 21:55 ]

~ Mijn prog blog!


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
PMA doet het inmiddels weer :) (zit trouwens op een shared server :P) en de index is toegevoegd aan time.
Alleen met de bovengenoemde query blijft hij nog steeds oneindig laden

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18-09 17:06

gorgi_19

Kruimeltjes zijn weer op :9

Saven schreef op zondag 01 februari 2009 @ 21:54:
PMA doet het inmiddels weer :) (zit trouwens op een shared server :P) en de index is toegevoegd aan time.
Alleen met de bovengenoemde query blijft hij nog steeds oneindig laden
En als je (in een testomgeving) er alles op 200 records uit gooit en door middel van een executionplan eens gaat kijken wat er precies gebeurd?

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

roy-t schreef op zondag 01 februari 2009 @ 21:48:
Het aantal records klinkt niet heel schrikwekkend, vziw heeft oa phpbb iig alle berichten in 1 tabel (geen apparte tabel per topic, wat nogal lastig zou worden op een gegeven moment :) )
Dat zou een wanstaltig gedrocht zijn security- en performancetechnisch :X Een aparte tabel per topic is onzin, maar losse tabellen voor topics en berichten zijn verplichte kost. Iets met appels en peren.
gorgi_19 schreef op zondag 01 februari 2009 @ 21:57:
[...]

En als je (in een testomgeving) er alles op 200 records uit gooit en door middel van een executionplan eens gaat kijken wat er precies gebeurd?
Ik heb zo'n vermoeden dat ie door de selfjoin/selfsubquery tegen MySQL's limieten aanloopt mbt max aantal indexes dat ie kan gebruiken per tabel (zijnde exact 1).

[ Voor 29% gewijzigd door curry684 op 01-02-2009 22:11 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 18-09 17:06

gorgi_19

Kruimeltjes zijn weer op :9

curry684 schreef op zondag 01 februari 2009 @ 22:09:
Ik heb zo'n vermoeden dat ie door de selfjoin/selfsubquery tegen MySQL's limieten aanloopt mbt max aantal indexes dat ie kan gebruiken per tabel (zijnde exact 1).
* gorgi_19 kent MySQL in dat opzicht totaal niet, dus ik heb geen idee wat een explain aan ranzigheden gaat blootleggen :P
Sowieso vraag ik me af het een iets andere structuur inderdaad niet dit problemen gaat voorkomen en voor tigmaal betere performance gaat zorgen :)

[ Voor 15% gewijzigd door gorgi_19 op 01-02-2009 22:13 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
En met deze query dan :P
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
            SELECT
                f.id, f.title, f.status
            FROM
                forum f
            JOIN
                forum r
            ON
                (r.tid=f.id)
            WHERE
                r.id = MAX(r.id)
            ORDER BY
                f.id
            DESC
            LIMIT
                :limit

Zou moeten werken, maar hij geeft de volgende error:
Foutmelding: SQLSTATE[HY000]: General error: 1111 Invalid use of group function

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Saven schreef op zondag 01 februari 2009 @ 23:10:
En met deze query dan :P
<snip>
Zou moeten werken, maar hij geeft de volgende error:
Foutmelding: SQLSTATE[HY000]: General error: 1111 Invalid use of group function
Doe jezelf en ons nou eens een lol en verdiep je in de basics van SQL. Je lijkt geen benul te hebben waar je mee bezig bent; en dat is geen ramp (we hebben het allemaal ooit moeten leren) maar we verwachten wel dat je een beetje eigen initiatief vertoont en niet dat wij iedere scheet mogen voorkauwen of je handje vasthouden.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Jaap-Jan
  • Registratie: Februari 2001
  • Laatst online: 23:11
Je gebruikt een aggregate function (MAX()) maar je query bevat geen group by, dus kan de database geen MAX() kiezen.

En met RobIII, je lijkt nog steeds de inhoud van Hoe werkt dat GROUP BY nu eigenlijk? niet te hebben begrepen. :)

[ Voor 45% gewijzigd door Jaap-Jan op 01-02-2009 23:18 ]

| 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!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
RobIII schreef op zondag 01 februari 2009 @ 23:17:
[...]

Doe jezelf en ons nou eens een lol en verdiep je in de basics van SQL. Je lijkt geen benul te hebben waar je mee bezig bent; en dat is geen ramp (we hebben het allemaal ooit moeten leren) maar we verwachten wel dat je een beetje eigen initiatief vertoont en niet dat wij iedere scheet mogen voorkauwen of je handje vasthouden.
Ja best slecht van mezelf, ik ben al zo'n 4 jaar bezig met php en mysql maar ik dacht dat ik mysql al aardig onder de knie had. heb het zelfs gehad op school :') :X

Maar ik zal ff kijken naar die reactie hier boven me :)

Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
SQL:
1
2
3
4
5
6
7
8
9
10
11
            SELECT
                tid, MAX(time) as last_time
            FROM
                forum
            GROUP BY
                tid
            ORDER BY
                id
            DESC
            LIMIT
                :limit

Ik heb even serieus gewerkt aan mijn GROUP BY skills :P en ik ben het maar van plan dan om het met meerdere queries te doen. Maar dan heb ik wel de laatste tijd nodig.
Ik wil dus het topic_id opvragen, gegroeppeerd, en de MAX(TIME) welke de tijd is van de laatste post.
Dan wil ik ze vervolgens aflopend gaan ordenen omdat ik de 5 titels ook aflopend wil hebben voor in mijn volgende query

Maar blijkbaar doe ik iets fout, want hij pakt nog steeds niet echt de allerlaatste tijden
Weet iemand wat ik fout doe?

edit: omfg, note to self: niet meer de scrollknop indrukken om te editen in een nieuwe tab terwijl je jezelf eigenlijk quote |:(

[ Voor 33% gewijzigd door Saven op 02-02-2009 00:31 ]


Acties:
  • 0 Henk 'm!

  • Cousin Boneless
  • Registratie: Juni 2008
  • Laatst online: 28-02 12:55
waar komt die 'id' opeens vandaan. Moet dat geen 'tid' zijn? Of beter nog: max(time)

Met die ene query (de vastloper) was je wel aardig op weg, maar ik vrees dat die LIMIT 1 in de subquery wel eens traag kan zijn. Dit zou je eens kunnen proberen:
SQL:
1
2
3
4
5
6
7
8
SELECT f.id, f.title, f.status
FROM forum f
WHERE f.time = (
    SELECT MAX(r.time)
    FROM forum r
    WHERE r.tid = f.tid 
)
ORDER BY f.time DESC

Of als inline view (mijn voorkeur in dit geval):
SQL:
1
2
3
4
5
6
7
8
9
10
SELECT r.tid, t.title, t.status, r.time, u.username
FROM (
    select tid, MAX(time) as max_time
    from forum
    group by tid
) r_max
INNER JOIN forum r ON r.time = r_max.time AND r.tid = r_max.tid
INNER JOIN forum t ON t.id = r.tid
INNER JOIN members u ON u.id = r.uid
ORDER BY r.time DESC


Je kan misschien nog wat performance winnen door early te checken of iets een topic is en zodoende een tid NULL zal bevatten.
SQL:
1
2
3
...
INNER JOIN (SELECT id, title FROM forum WHERE tid IS NULL) t ON t.id = r.tid
...


Maar zoals al gezegd: Niet echt handig om topics en reacties in één tabel te stoppen (ook gezien het aantal records dat nu gefilterd moet worden om topics te bepalen)

[ Voor 106% gewijzigd door Cousin Boneless op 03-02-2009 01:13 ]


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Dankje Cousin Boneless :)
Die eerste query werkt inderdaad niet echt, blijft heel lang door laden :P

Die tweede doet het wel. Alleen die geeft de tijden nog steeds niet echt goed weer. En ordert ze ook niet goed.
Ik had je query iets aangepast omdat hij het niet deed :P
SQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT r.tid, t.title, t.status, r.time, u.username
FROM (
    select tid, MAX(time) as max_time
    from forum
    group by tid
) r_max
INNER JOIN forum r ON (r.time = r_max.max_time AND r.tid = r_max.tid)
INNER JOIN forum t ON t.id = r.tid
INNER JOIN members u ON u.id = r.uid
ORDER BY r.time DESC
LIMIT :limit


Ik denk dat het komt omdat hij de laaste reactie tijden van de laatste topics pakt, en niet de echte laatste reactie tijden

Acties:
  • 0 Henk 'm!

  • Cousin Boneless
  • Registratie: Juni 2008
  • Laatst online: 28-02 12:55
De haakjes om de join-conditie? Zou geen verschil mogen maken..
Ow r_max.time moest r_max.max_time zijn :)

Maar nog steeds niet de juiste resultaten dus. Enige wat ik kan bedenken is dat er meerdere reacties binnen het topic een gelijke timestamp hebben, of dat een topic via het tid-veld naar zichzelf verwijst. (en dat het topic zelf de meest recente stamp heeft), of dat de user van de laatste reactie niet bestaat en daardoor de topic wegvalt.

Iig.. de subquery ('geef mij per topic het tijdstip van de laatste reactie') is de motor in het geheel. De rest is er één op één aan gekoppeld. Dus als het misgaat, dan zou het al in dat stukje moeten zitten.

Edit: nog een optie: misschien moet je je indexen rebuilden

[ Voor 11% gewijzigd door Cousin Boneless op 02-02-2009 21:39 ]


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Cousin Boneless schreef op maandag 02 februari 2009 @ 21:16:
of dat een topic via het tid-veld naar zichzelf verwijst. (en dat het topic zelf de meest recente stamp heeft)
Mijn 2 centen staan op deze :P

Allemaal te voorkomen met een simpele wijziging naar een goed datamodel ;)

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Als je geen goed datamodel hebt, zou ik eerst eens een paar views maken. Dus iets als:
SQL:
1
2
create view topics as select id as topicId, title, status, ... from forum where id=tid;
create view posts as select id as postId, tid as topicId, uid, time, ... from forum;

Maar eigenlijk wil je gewoon zsm die forum-tabel weggooien. :)

Vervolgens kun je een groupwise max constructie met limit gebruiken voor de resultaten. Die constructie van C.B. is denk op zich goed, maar wat minder geschikt in combinatie met limit vanwege de snelheid. MySQL is/was niet zo goed in sorteren op max(...). Ik heb dit niet getest, maar ik zou eerder denken aan iets als:
SQL:
1
2
3
4
5
6
7
8
9
10
select t.topicId, t.title, t.status, p.time, m.username
from posts as p 
    inner join topics as t using (topicId) 
    inner join members as m on p.uid=m.id
where not exists 
    (select * from posts as p2 
     where (p2.time>p.time or (p2.time=p.time and p2.postId>p.postId)) 
         and p.topicId=p2.topicId)
order by p.time desc
limit :limit;

En als dat niet snel genoeg is, kun je eens wat andere queries uitproberen. Je zou ook de laatste post voor ieder topic bij kunnen houden, phpbb doet dat dacht ik.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Hm na al deze comments gelezen te hebben denk ik dat ik toch maar terug ga op het oorspronkelijke model. een tabel topics en een tabel reacties (voor de nieuwe versie dan wel te verstaan waar ik nu dus mee bezig ben).

Maar kan ik hiermee nog een goed zoek-systeem. Welke live is. Dus niet met een aparte zoektabel ofzo werkt dat ik alle topics moet indexeren like google style :P en die dan in een tabel forum_geindexeerd doe ofzo :P

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Voor dit soort 'kleine' fora leg je gewoon een fulltext index op je reacties tabel - waarom zou dat niet werken?

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Nou omdat ik de tabel forum_topics EN forum_reacties moet doorzoeken :P
Dat probleem had ik eerst ook. Toen had ik de topics en reacties ook apart. Maar toen kon ik de results niet goed ordenen enzo. Hij pakte eerst de topics en toen pas de reacties. Terwijl ik ze gewoon op tijd wou ordenen.

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Waarom zou je de topicstabel inhoudelijk willen doorzoeken? :?

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
omdat als ik ga zoeken naar de term bijvoorbeeld 'koetjesrepen' ik natuurlijk ook wil kijken of die in de topicstart gebruikt wordt

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Waarom zou je de topicstart in de topicstabel willen zetten? :?

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
uh.
nu snap ik het helemaal niet meer :P

je hebt toch 1 tabel topics
met id, titel, bericht, userid etc..

en 1 tabel reacties
met
id, topic_id, bericht, userid etc..

tenminste, dat lijkt mij het meest logische?

[ Voor 12% gewijzigd door Saven op 03-02-2009 00:14 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Saven schreef op dinsdag 03 februari 2009 @ 00:14:
tenminste, dat lijkt mij het meest logische?
Mij niet, want een topicstart verschilt niets van de andere replies. Het is gewoon een reply, en als je de replies op tijd sorteert ophaalt, staat hij netjes bovenaan.

Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
waarom zou ik dan een topic tabel maken :+? :P
Want dan is het hetzelfde wat ik nou heb, alleen zou ik dan de status van het topic enzo in een andere tabel zetten. Maakt weinig verschil lijkt me

(breek me er niet op af als ik nu weer onlogisch bezig ben :$ zo heel veel ervaring met goede DB's heb ik nou ook weer niet :))

[ Voor 90% gewijzigd door Saven op 03-02-2009 00:24 ]


Acties:
  • 0 Henk 'm!

  • Cousin Boneless
  • Registratie: Juni 2008
  • Laatst online: 28-02 12:55
waarom zou ik dan een topic tabel maken
Best een goeie... Dat is alleen een id en een naam. En zelfs de naam is redundant, omdat dit ook door de eerste reply wordt bepaald. Dus topic is eigenlijk geen entiteit.
Maar dat betekent dus ook dat je in je reply tabel nooit een record kan/mag hebben dat de topic representeert en die fout heb je nu wel gemaakt.

Acties:
  • 0 Henk 'm!

  • ZaZ
  • Registratie: Oktober 2002
  • Laatst online: 19-08 14:24

ZaZ

Tweakers abonnee

Probeer iets meer abstract te denken. Waarin verschilt een topicstart van een 'normale' post, behalve dat ie toevallig de eerste is?
Kijk alleen naar wat nodig is en probeer niet alles wat je in je presentatielaag wilt zien op te slaan in je database. Zoals het nu overkomt zou je misschien ook overwegen om de replycount per topic op te slaan in je topicstable (bedoel het niet lullig)
Dat soort dingen kan alleen voor redundante data zorgen en dat wil je niet.

Als je kiest voor een model van topic en reacties, waarom dan niet alleen bijvoorbeeld een titel en id in je topic table en alle reacties in je reacties table?

Lekker op de bank


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Cousin Boneless schreef op dinsdag 03 februari 2009 @ 01:02:
[...]

Best een goeie... Dat is alleen een id en een naam. En zelfs de naam is redundant, omdat dit ook door de eerste reply wordt bepaald. Dus topic is eigenlijk geen entiteit.
Id, titel, status, forum, ...
Maar dat betekent dus ook dat je in je reply tabel nooit een record kan/mag hebben dat de topic representeert en die fout heb je nu wel gemaakt.
Het is geen tabel met reply's, maar met posts. Ook de startpost is gewoon een post :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Saven schreef op dinsdag 03 februari 2009 @ 00:21:
waarom zou ik dan een topic tabel maken :+? :P
Want dan is het hetzelfde wat ik nou heb, alleen zou ik dan de status van het topic enzo in een andere tabel zetten. Maakt weinig verschil lijkt me

(breek me er niet op af als ik nu weer onlogisch bezig ben :$ zo heel veel ervaring met goede DB's heb ik nou ook weer niet :))
Als je de basisregels van normaliseren er eens op na zou slaan zou je daar heel vroeg tegenkomen dat een tabel geen fields mag bevatten die niet specifiek zijn voor de geencapsuleerde entiteit: je zet de fields die bij een topic horen in de tabel topic, en de fields die bij een post horen bij de posts. Een topic heeft bijvoorbeeld:
- Een uniek identificatienummer
- Een status (gesloten, open, sticky?)
- Een titel
- Een referentie naar het forum waarin hij staat

Een post heeft bijvoorbeeld:
- Een referentie naar de poster
- Een referentie naar zijn topic
- De inhoud
- De datum van plaatsen

Vervolgens kom je tegen een aantal performance issues aan met betrekking tot het vinden van de topicstarter, de last post time en de replycount als je die realtime wil opzoeken. Deze 'denormaliseer' je dus naar je topics tabel.

Respect overigens dat je een forum met 100k posts hebt weten te bouwen zonder de basisbeginselen van databases ooit te (hebben willen) snappen 8)7 Ik zou er als ik jou was toch echt even een boekje op naslaan, of [google=normaliseren].
ZaZ schreef op dinsdag 03 februari 2009 @ 01:02:
Zoals het nu overkomt zou je misschien ook overwegen om de replycount per topic op te slaan in je topicstable (bedoel het niet lullig)
Hoe dacht je dat dit forum waar je op zit het deed? ;) Jij mag [google=denormaliseren], niet lullig bedoeld :P

[ Voor 12% gewijzigd door curry684 op 03-02-2009 02:08 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • ZaZ
  • Registratie: Oktober 2002
  • Laatst online: 19-08 14:24

ZaZ

Tweakers abonnee

curry684 schreef op dinsdag 03 februari 2009 @ 02:02:
[...]
[...]

Hoe dacht je dat dit forum waar je op zit het deed? ;) Jij mag [google=denormaliseren], niet lullig bedoeld :P
I stand corrected :)

Lekker op de bank


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
ZaZ schreef op dinsdag 03 februari 2009 @ 01:02:
Probeer iets meer abstract te denken. Waarin verschilt een topicstart van een 'normale' post, behalve dat ie toevallig de eerste is?
Kijk alleen naar wat nodig is en probeer niet alles wat je in je presentatielaag wilt zien op te slaan in je database. Zoals het nu overkomt zou je misschien ook overwegen om de replycount per topic op te slaan in je topicstable (bedoel het niet lullig)
Dat soort dingen kan alleen voor redundante data zorgen en dat wil je niet.

Als je kiest voor een model van topic en reacties, waarom dan niet alleen bijvoorbeeld een titel en id in je topic table en alle reacties in je reacties table?
Je hebt helemaal gelijk :) Alleen het lijkt mij toch wel het meest verstandige om de starter_id (de user), de reply_count en last_post_time ook in de topics tabel op te slaan. Zeker voor de performance :P
curry684 schreef op dinsdag 03 februari 2009 @ 02:02:
[...]

Als je de basisregels van normaliseren er eens op na zou slaan zou je daar heel vroeg tegenkomen dat een tabel geen fields mag bevatten die niet specifiek zijn voor de geencapsuleerde entiteit: je zet de fields die bij een topic horen in de tabel topic, en de fields die bij een post horen bij de posts. Een topic heeft bijvoorbeeld:
- Een uniek identificatienummer
- Een status (gesloten, open, sticky?)
- Een titel
- Een referentie naar het forum waarin hij staat

Een post heeft bijvoorbeeld:
- Een referentie naar de poster
- Een referentie naar zijn topic
- De inhoud
- De datum van plaatsen

Vervolgens kom je tegen een aantal performance issues aan met betrekking tot het vinden van de topicstarter, de last post time en de replycount als je die realtime wil opzoeken. Deze 'denormaliseer' je dus naar je topics tabel.

Respect overigens dat je een forum met 100k posts hebt weten te bouwen zonder de basisbeginselen van databases ooit te (hebben willen) snappen 8)7 Ik zou er als ik jou was toch echt even een boekje op naslaan, of [google=normaliseren].
Echt super bedankt voor de uitleg _/-\o_ ben een heel stuk wijzer geworden :P
Maar dat denormaliseren van de last_post_time en starter_id (de user die het topic startte) is dus niks mis mee begrijp ik :)
Ik heb namelijk ook zitten spieken bij IPB 2.3 en die slaat dat ook op in zijn topics tabel :)

En zou het misschien verstandig zijn om in de posts tabel nog een veld te maken, met is_topic? Dan zou ik bijvoorbeeld makkelijker het aantal topics kunnen tellen voor de forumindex. Of als iemand zijn topic wil bewerken inclusief de topictitel :)

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Saven schreef op dinsdag 03 februari 2009 @ 12:18:
Echt super bedankt voor de uitleg _/-\o_ ben een heel stuk wijzer geworden :P
Maar dat denormaliseren van de last_post_time en starter_id (de user die het topic startte) is dus niks mis mee begrijp ik :)
Dat zomaar doen is wel wat mis mee. Eerst normaliseren en dan een overwogen en verdedigbaar besluit nemen om sommige dingen te denormaliseren en vervolgens een strategie afstemmen om ervoor te zorgen dat die gegevens wel up to date blijven.
En zou het misschien verstandig zijn om in de posts tabel nog een veld te maken, met is_topic? Dan zou ik bijvoorbeeld makkelijker het aantal topics kunnen tellen voor de forumindex. Of als iemand zijn topic wil bewerken inclusief de topictitel :)
Waarom? Een post is een post en geen topic. Wat denk je hier uberhaupt mee op te schieten?

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Zoals ik al aangaf, op de forum index tel ik posts en reacties per subforum.
Als ik dan een veld is_topic heb, hoef ik die alleen maar te tellen en ik weet het topic. Waar ik mij nu net 2 seconden geleden realiseer dat dat nergens op slaat :p
Maar voor een post te bewerken zou dat wel handig zijn toch. Want dan edit ik de beginpost maar dat blijkt dan een topic te zijn.
Dan hoef ik niet een extra query te gebruiken om te checken of de post die ik wil editen een topic is of niet

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

Een begin post is geen topic. Waarom is het wijzigen van de startpost anders dan het wijzigen van een andere post? Het wijzigen van een topictitel lijkt me een andere usecase dan het wijzigen van je post.

Mocht je uiteindelijk nog steeds niet overtuigd zijn, dan nog is het uit normalisatie oogpunt imho logischer om juist in de topic tabel een referentie naar de post op te nemen ipv andersom.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Maar hoe zit dat dan als ik reacties wil tellen totaal in een forum voor op de forum index, of in een topiclijst in in een forum de reacties wil tellen op een topic.
Dan moet ik of heel moeilijk gaan doen door te kijken welke posts niet de startpost zijn.

Bij de topiclijst zou ik nog slordig kunnen doen door -1 te gebruiken :P maar bij de forumindex wordt dat al lastiger.

met een extra kolom is_topic in de forum_posts tabel zou dat al een stuk makkelijker zijn imo :P

[ Voor 11% gewijzigd door Saven op 03-02-2009 13:55 ]


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Saven schreef op dinsdag 03 februari 2009 @ 13:54:
Maar hoe zit dat dan als ik reacties wil tellen totaal in een forum voor op de forum index, of in een topiclijst in in een forum de reacties wil tellen op een topic.
Dan moet ik of heel moeilijk gaan doen door te kijken welke posts niet de startpost zijn.
Hoezo is dat een probleem? Een topic heeft count(PostId) messages, en count(PostId)-1 replies. Dat is basale logica.
Bij de topiclijst zou ik nog slordig kunnen doen door -1 te gebruiken :P
Hoezo is dat slordig? Lees deze mededeling nog eens en denk eens na over de consequenties van dat chemmetje daar 312 in z'n UPDATE heeft staan en 311 in de titel van het topic ;)
maar bij de forumindex wordt dat al lastiger
Wees om te beginnen al eens niet zo bezeten met het verschil tussen replies en messages ;) Een net geopend topic heeft gewoon 0 replies en 1 message, logisch toch? En als je totaal aantal reacties perse wil hebben is dat gewoon count(PostId)-count(TopicId), ook logisch toch?
met een extra kolom is_topic in de forum_posts tabel zou dat al een stuk makkelijker zijn imo :P
Nee want een post is nooit een topic. Topics staan in een aparte tabel.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Haha oke 'Nee want een post is nooit een topic.' i get that one :P
Maar ik denk dat ik er nu wel helemaal uit moet komen :)

iig allemaal bedankt :*) d:)b
Ik ben weer een stuk wijzer dankzij u allen ;)

Nogmaals bedankt! d:)b

Acties:
  • 0 Henk 'm!

  • cariolive23
  • Registratie: Januari 2007
  • Laatst online: 18-10-2024
roy-t schreef op zondag 01 februari 2009 @ 19:25:
[...]


Hoewel group-by misschien toch uitgevoerd wordt ondanks dat het een niet 'perfecte' query is zou ik mijn MySQL database iig nooit afstellen naar aanlijding van dit document (excuses als je het zelf hebt geschreven) het aantal keren dat er staat 'waarom dit wel kan weet ik niet maar doe het maar uit, want in situatie x kan het onwenselijk zijn' weet ik niet, maar het zijn er aanzienlijk veel.

Verder hebben de meeste mensen zelf geen invloed op de configuratie van hun mysql database, en als ze dat wel hebben vraag ik toch heel lief om er alleen aan te zitten als je toch echt op een veel hoger niveau bezig bent met databases.

We hebben het hier gewoon over een group-by/order-by foutje laten we het daar over hebben :) .
Wat MySQL nu doet, is wiskundig onmogelijk. Je kunt geen groep maken en dan een detail opvragen van een specifiek record. Dat is onmogelijk! Dat MySQL hier maar een gokje gaat wagen, leuk en aardig, maar dat is wat anders dan een correct resultaat.

SELECT voornaam, achternaam FROM gebruikers GROUP BY achternaam;

Wat is nu de voornaam van de groep gebruikers met de achternaam 'Jansen' ? Er zijn wel wellicht duizenden mensen met de achternaam 'Jansen', dat kunnen dus duizenden voornamen zijn. Welke voornaam moet de database nu dan als antwoord oplepelen? 'Piet' ? Dat is fout, er zijn ook gebruikers met bv. de voornaam 'Jan'. De query is grote onzin en gewoon fout. Dat had dus een fraaie foutmelding moeten worden. Dat MySQL dat niet doet, zegt een hoop over de kwaliteit van MySQL.

Je kunt de configuratie runtime goed zetten, dat mag dus geen (groot) probleem zijn. Uiteraard kun je ook een betere database nemen, eentje die standaard al snapt hoe de wiskunde in elkaar zit...

Ps. Genoemd artikel is niet van mijn hand.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
cariolive23 schreef op dinsdag 03 februari 2009 @ 18:18:
De query is grote onzin en gewoon fout.
Waarom schrijf je hem dan op?... ;)

Wat dacht je van het volgende betere voorbeeld:
SQL:
1
2
select p.persoonId,p.voornaam,p.achternaam,count(o.orderId) 
from personen p natural left join orders o group by p.persoonId

Wat is hier fout aan? Lees ook dit artikel.
Dat had dus een fraaie foutmelding moeten worden. Dat MySQL dat niet doet, zegt een hoop over de kwaliteit van MySQL.

Je kunt de configuratie runtime goed zetten, dat mag dus geen (groot) probleem zijn. Uiteraard kun je ook een betere database nemen, eentje die standaard al snapt hoe de wiskunde in elkaar zit...
Of het zegt iets over de mogelijkheid tot efficiency... :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 16-09 09:15

Janoz

Moderator Devschuur®

!litemod

pedorus schreef op dinsdag 03 februari 2009 @ 19:50:
Wat dacht je van het volgende betere voorbeeld:
SQL:
1
2
select p.persoonId,p.voornaam,p.achternaam,count(o.orderId) 
from personen p natural left join orders o group by p.persoonId

Wat is hier fout aan?
Geen idee welke voornaam of achternaam er genomen moet worden, of moet ik maar aannemen dat persoonId uniek is?


Het hele artikel vind ik persoonlijk een heel lange rechtbrei poging van een vreemde ontwerp beslissing.

[ Voor 11% gewijzigd door Janoz op 03-02-2009 20:13 ]

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Janoz schreef op dinsdag 03 februari 2009 @ 20:09:
[...]

Het hele artikel vind ik persoonlijk een heel lange rechtbrei poging van een vreemde ontwerp beslissing.
Dat is heel MySQL zelf ook ergens sinds v3 of zo, net als PHP sinds v4 ;)

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
pedorus schreef op dinsdag 03 februari 2009 @ 19:50:
Wat dacht je van het volgende betere voorbeeld:
SQL:
1
2
select p.persoonId,p.voornaam,p.achternaam,count(o.orderId) 
from personen p natural left join orders o group by p.persoonId

Wat is hier fout aan?
Als je zeker weet dat het rdms eerst in een meta tabel op gaat zoeken of persoonId uniek is, zou het niet fout zijn. Als je rdms dat niet doet (en dat doet een rdms normaliter niet) weet je niet of je valide data terug krijgt. Dan kun je beter een error uitpoepen, dan gewoon wat random data nemen. :)

Waarom zou je de verantwoordelijkheid voor het juist interpreteren van dit soort queries uberhaupt bij het rdms willen leggen? Ik wil een error als ik iets fout doe. :)

[ Voor 3% gewijzigd door Alain op 03-02-2009 21:18 ]

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Syntactisch mag het gewoon niet, unique constraint op persoonId of niet. Programmeertalen, waaronder ook SQL, kunnen syntactisch niet valideren op inhoudelijke beslissingen - een query compileert wel of niet. Als het situatieafhankelijk is is het dus niet.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Alain
  • Registratie: Oktober 2002
  • Niet online
curry684 schreef op dinsdag 03 februari 2009 @ 21:22:
Syntactisch mag het gewoon niet, unique constraint op persoonId of niet. Programmeertalen, waaronder ook SQL, kunnen syntactisch niet valideren op inhoudelijke beslissingen - een query compileert wel of niet. Als het situatieafhankelijk is is het dus niet.
Als ik een bestand wil openen weet ik tijdens het compileren ook nog niet of het bestand bestaat. Ik wil niet zeggen dat de SQL syntax aangepast moet worden op verkeerd geschreven queries, maar theoretisch zou het toch moeten kunnen?

You don't have to be crazy to do this job, but it helps ....


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Theoretisch kunnen zoveel dingen die pertinent een slecht idee zijn :+

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Janoz schreef op dinsdag 03 februari 2009 @ 20:09:
Geen idee welke voornaam of achternaam er genomen moet worden, of moet ik maar aannemen dat persoonId uniek is?
In een logisch database design is entityId uniek voor de tabel entities ja... Maar ik zal het je geven, de volgende functionele afhankelijkheden bestaan:
in personen: persoonId->voornaam,achternaam
in orders: orderId->persoonId
Het hele artikel vind ik persoonlijk een heel lange rechtbrei poging van een vreemde ontwerp beslissing.
Het zou ze sieren als ze ook een echte standaard-compatible-modus hadden gemaakt, die de afhankelijkheden checkt aan de hand van keys. Dat zou dan een goede modus zijn om de code te testen.
curry684 schreef op dinsdag 03 februari 2009 @ 22:13:
Theoretisch kunnen zoveel dingen die pertinent een slecht idee zijn :+
Goed argument ;) Ik heb toch het idee dat dit een beetje een heilig huisje is: 'gij zult altijd alle niet-geaggregeerde kolommen in de group by specificeren'. Terwijl echte redenen ontbreken. Een group by optimalisatie zal die extra opgegeven attributen in de group by eerst weg proberen te halen aan de hand van keys, omdat je anders onnodige vergelijkingen gaat doen. Waarom moeten programmeurs ze dan onnodig gaan opschrijven? Ik heb wel iets beters te doen :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Maaruhm zoals je zelf al aangeeft is deze 'optimalisatie' enkel mogelijk op kolommen met een unique constraint. Wat is het nut van groupen op een kolom met een unique constraint eigenlijk?

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Saven
  • Registratie: December 2006
  • Laatst online: 21:57

Saven

Administrator

Topicstarter
Even weer een kleine bump van mijn kant. Zoals mij is verteld (en zoals ik weet) is een post geen topic. een kolom is_topic gebruiken in de forum_posts tabel klopt dan niet.
Maar is het wel een 'goed' idee om een veld 'is_startpost' te gebruiken? Heet anders dan is_topic maar komt eigenlijk op hetzelfde neer.

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Dat is gedenormaliseerde data voor de post binnen topic X met de laagste reactietijd. Welk nut heeft het dan om die data toe te voegen?

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:16
pedorus schreef op woensdag 04 februari 2009 @ 00:42:
[...]

Ik heb toch het idee dat dit een beetje een heilig huisje is: 'gij zult altijd alle niet-geaggregeerde kolommen in de group by specificeren'. Terwijl echte redenen ontbreken.
Hmmm:

code:
1
2
3
4
use adventureworks
select nationalidnumber, contactid, managerid, count(*)
from HumanResources.Employee
group by managerid

:
code:
1
2
Msg 8120, Level 16, State 1, Line 2
Column 'HumanResources.Employee.NationalIDNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
curry684 schreef op woensdag 04 februari 2009 @ 01:10:
Maaruhm zoals je zelf al aangeeft is deze 'optimalisatie' enkel mogelijk op kolommen met een unique constraint. Wat is het nut van groupen op een kolom met een unique constraint eigenlijk?
Komt veel voor in rapportages, in combinatie met joins natuurlijk.
whoami schreef op woensdag 04 februari 2009 @ 19:44:
code:
1
2
Msg 8120, Level 16, State 1, Line 2
Column 'HumanResources.Employee.NationalIDNumber' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Even vooropgesteld dat de functionele afhankelijkheden bestaan waardoor dat een zinnige query zou kunnen zijn (managerid->nationalidnumber, contactid):
Blijkbaar is SQL Server niet in overeenstemming met SQL:2003? :Y)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

pedorus schreef op woensdag 04 februari 2009 @ 21:02:
[...]

Komt veel voor in rapportages, in combinatie met joins natuurlijk.
Wtf dat moet je me toch eens langzaam uitleggen..... groupen op een column met een unique constraint gaat per definitie nooit rows filteren, wat is dan het nut ervan? :?

* curry684 is het even kwijt.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
curry684 schreef op woensdag 04 februari 2009 @ 21:20:
[...]

Wtf dat moet je me toch eens langzaam uitleggen..... groupen op een column met een unique constraint gaat per definitie nooit rows filteren, wat is dan het nut ervan? :?
Die unieke constraint gaat over 1 tabel. Na te joinen over een 1-many relatie geld die constraint niet meer voor het resultaat van de join natuurlijk. De functionele afhankelijkheid (vb:persoonId->achternaam) geld echter nog steeds. Als je een vraag krijgt van het type 'geef het aantal transacties per klant', dan wil je vaak niet alleen het klantId weten, maar ook wat andere identificerende gegevens.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

pedorus schreef op woensdag 04 februari 2009 @ 21:48:
[...]

Die unieke constraint gaat over 1 tabel. Na te joinen over een 1-many relatie geld die constraint niet meer voor het resultaat van de join natuurlijk. De functionele afhankelijkheid (vb:persoonId->achternaam) geld echter nog steeds. Als je een vraag krijgt van het type 'geef het aantal transacties per klant', dan wil je vaak niet alleen het klantId weten, maar ook wat andere identificerende gegevens.
Uhm ja maar hierdoor vervalt je hele voorbeeld omdat de query dan nog steeds nutteloos is tenzij je *OOK* op andere fields groupt waardoor je alsnog een complexe group hebt waarin je moet aangeven wat er met de restresultaten gebeurt. Je verschuift het probleem maar de essentie blijft hetzelfde: groupen op een unique constraint is nutteloos tenzij side effect van een complexere grouping.

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
curry684 schreef op woensdag 04 februari 2009 @ 22:50:
[...]

Uhm ja maar hierdoor vervalt je hele voorbeeld omdat de query dan nog steeds nutteloos is tenzij je *OOK* op andere fields groupt waardoor je alsnog een complexe group hebt waarin je moet aangeven wat er met de restresultaten gebeurt. Je verschuift het probleem maar de essentie blijft hetzelfde: groupen op een unique constraint is nutteloos tenzij side effect van een complexere grouping.
pedorus schreef op dinsdag 03 februari 2009 @ 19:50:
SQL:
1
2
select p.persoonId,p.voornaam,p.achternaam,count(o.orderId) 
from personen p natural left join orders o group by p.persoonId
Ik zie toch echt maar 1 field in de group by staan, welke in de orginele tabel een unique key (zelfs primary key) zal zijn.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
@group by discussie ben ik eigenlijk vrij simpel in.
Het heeft weinig nut behalve wat extra tikwerk besparen en het voegt een onnodig ( niet-gestandaardiseerd ) niveau van complexiteit toe.

Als mysql het alsnog afkeurde als er niet alleen unique keys niet gegroepeerd waren dan viel er nog iets voor te zeggen, maar huidige implementatie leidt imho alleen maar tot slordig programmeren ( niet alles hoeft in de group by te staan ) door gewoon undefined results terug te geven in toekomstige situaties.

Huidige implementatie vind ik nog erger dan goto. Heel soms kan het handig zijn mits 100% juist gebruikt, in de praktijk zijn 999 vd 1000 implementaties gewoon verkeerd / lui gebruik wat bugs in de toekomst veroorzaakt...

Acties:
  • 0 Henk 'm!

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

curry684

left part of the evil twins

Ik zei het niet bepaald lekker maar punt blijft dat die query fout is omdat z'n succesvolle executie afhankelijk is van de inhoud van de database in plaats van de vorm. Checken van unique constraints is niet voldoende daar een unique constraint (conform ANSI-SQL) duplicate NULL values toestaat conform de stelling NULL != NULL, wat alleen primary keys en unique constraints op non-nullable fields over laat als candidate voor deze shorthand.

De syntaxoptimalisatie die je voorstelt kan dus enkel een handjevol velden wegoptimaliseren indien het RDBMS tijdens query compilation inhoudelijk verifieert dat missende velden in een GROUP toegestaan zijn mits alle primary key cq. non-nullable uniquely constrained fields gerelateerde doch expliciet geen overige velden uit de tabel in kwestie gegrouped zijn.

Volgens mij maak je het hiermee alleszins niet simpeler voor de paar exotische analytische queries waar het relevant zou zijn 8)7

[ Voor 5% gewijzigd door curry684 op 05-02-2009 00:03 ]

Professionele website nodig?


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Gomez12 schreef op woensdag 04 februari 2009 @ 23:43:
Als mysql het alsnog afkeurde als er niet alleen unique keys niet gegroepeerd waren dan viel er nog iets voor te zeggen, maar huidige implementatie leidt imho alleen maar tot slordig programmeren ( niet alles hoeft in de group by te staan ) door gewoon undefined results terug te geven in toekomstige situaties.
Niet enkel toekomstige situaties! Incomplete group by clauses kunnen al jaren voor non deterministische data zorgen. Als je zelf alle velden met een func. afhankelijkheid erin zet zit je echter wel safe, maar dat is niet iets dat door mysql gecontroleerd wordt, dus bij een structuurverandering mag (moet) je weer lekker nadenken over de correctheid van je queries met group by.

Overigens kan mysql wel middels een SQL_MODE deze error voortaan wel gooien, alleen jammer dat SQL_MODE inmiddels met stip de grootste design failure is in mysql. Het is aan te passen per sessie dus je dbms kan per sessie totaal anders werken, het is aan te passen zonder speciale rechten en het is default op de minst stricte instelling. De combinatie van deze regels is overigens ook spectaculair: Iedere lutser met een db login kan een applicatie sql errors laten krijgen door de SQL_MODE een slinger te geven.

Een compatability optie als SQL_MODE lijkt in eerste instantie een goed idee, maar als er steeds meer modes bijkomen, er nooit een brekende wijziging gemaakt durft te worden en nooit de default aangepast wordt (en dan nog c/p'en genoeg admins de vorige config...) wordt het ironisch genoeg juist een enorme hel om alles compatibel te houden. Het is dan ook de eerste feature welke er bij Drizzle uitgesloopt is (en Drizzle is dus gewoon altijd stricter), want daarmee elimineer je meteen honderden soorten gedrag en een complete categorie van lastige bugs.
[/rant]

Leesvoer hierover: http://code.openark.org/blog/mysql/do-we-need-sql_mode

{signature}


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
curry684 schreef op donderdag 05 februari 2009 @ 00:02:
Ik zei het niet bepaald lekker maar punt blijft dat die query fout is omdat z'n succesvolle executie afhankelijk is van de inhoud van de database in plaats van de vorm. Checken van unique constraints is niet voldoende daar een unique constraint (conform ANSI-SQL) duplicate NULL values toestaat conform de stelling NULL != NULL, wat alleen primary keys en unique constraints op non-nullable fields over laat als candidate voor deze shorthand.
Bij een primary key kun je sowieso geen null-waardes hebben en dit is het meest voorkomende geval. Bij een unique key kun je het afleiden aan de hand van de de query (joins, vergelijkingen), maar het kan ook zijn dat not null gespecificeerd wordt in de tabeldefinitie. Naar de inhoud van de database kijken lijkt me inderdaad geen goed idee.
Gomez12 schreef op woensdag 04 februari 2009 @ 23:43:
@group by discussie ben ik eigenlijk vrij simpel in.
Het heeft weinig nut behalve wat extra tikwerk besparen en het voegt een onnodig ( niet-gestandaardiseerd ) niveau van complexiteit toe.
Het is dus ok volgens de standaard SQL:2003. Daarnaast heeft het als bijkomend voordeel dat je sneller kan zien waarop echt gegroepeerd wordt. En dan is er nog het geval van groeperen op memo-velden/BLOBs, wat je zo kan vermijden.
Huidige implementatie vind ik nog erger dan goto. Heel soms kan het handig zijn mits 100% juist gebruikt, in de praktijk zijn 999 vd 1000 implementaties gewoon verkeerd / lui gebruik wat bugs in de toekomst veroorzaakt...
Voor productie lijkt me het niet echt een probleem, omdat foute querys er al in de testomgeving uitgehaald moeten worden. Het is alleen erg jammer dat MySQL daar geen goede modus voor heeft...
Nou ja, bereid je alvast maar voor om al je backticks te gaan vervangen naar double quotes dan he. Het idee van 1 instelling per installatie zal vast ook heel leuk gevonden worden in shared hosting situaties... :)

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
pedorus schreef op donderdag 05 februari 2009 @ 10:13:
Nou ja, bereid je alvast maar voor om al je backticks te gaan vervangen naar double quotes dan he.
Syntactic sugar. Kan me echt niet boeien, zolang het maar consistent toegepast wordt. Van een eventuele replace lig ik echt niet wakker, zeker niet als zaken daarmee consistenter worden.
Het idee van 1 instelling per installatie zal vast ook heel leuk gevonden worden in shared hosting situaties... :)
Je zegt het nu sarcastisch, maar dit is juist de natte droom van menig virtuele hosting company! Zij zijn juist een vd partijen welke gebaat is bij de eenduidiger config en het verdwijnen van eerder genoemde categorie bugmeldingen.

{signature}


Acties:
  • 0 Henk 'm!

  • Gomez12
  • Registratie: Maart 2001
  • Laatst online: 17-10-2023
pedorus schreef op donderdag 05 februari 2009 @ 10:13:
[...]

Het is dus ok volgens de standaard SQL:2003. Daarnaast heeft het als bijkomend voordeel dat je sneller kan zien waarop echt gegroepeerd wordt. En dan is er nog het geval van groeperen op memo-velden/BLOBs, wat je zo kan vermijden.
Bold stukje : en dat het onduidelijker wordt wat er met de niet gegroepeerde velden gebeurt.
Imho maak je het juist onduidelijker waarop je groepeert zolang er voor de rest van de velden geen requirements zijn.

Het nadeel van de mysql implementatie is namelijk dat er geen harde limiet (/cq foutmelding ) aan zit. Zonder foutmelding kan je niet zien waarop echt gegroepeerd wordt. Je hebt namelijk nog geen idee of de andere velden unique keys zijn of gewoon undefined waardes zolang je niet in de dbase kijkt.
[...]

Voor productie lijkt me het niet echt een probleem, omdat foute querys er al in de testomgeving uitgehaald moeten worden. Het is alleen erg jammer dat MySQL daar geen goede modus voor heeft...
Mijn punt is juist dat je dit bijna niet in test-omgeving kan simuleren. Je app kan unique id's afdwingen zolang je dbase dit niet doet blijf je het gat openhouden dat een dba in de toekomst doublures introduceert wat in je app tot onverwachte resultaten kan leiden.
Dan kan je je app tot treurens toe gaan testen, die laat geen doublures toe... Alleen als er ooit een doublure is dan heb je pas een bug...

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Gomez12 schreef op vrijdag 06 februari 2009 @ 20:38:
Bold stukje : en dat het onduidelijker wordt wat er met de niet gegroepeerde velden gebeurt.
Imho maak je het juist onduidelijker waarop je groepeert zolang er voor de rest van de velden geen requirements zijn.
Hoezo? De opgevraagde ongenoemde velden zijn blijkbaar functioneel afhankelijk van de velden in de group by. De zo ontstane query bevat dus extra informatie, naast dat het minder tikwerk is: je laat iets zien over de functionele afhankelijkheden in de database. Als alle niet-geaggregeerde opgevraagde velden in de group by clause vermeld worden, dan bevat een groot gedeelte van die clause geen extra informatie, en is het lezen daarvan redelijk onnutig. En scannen moet je hem wel, voor het geval er extra velden vermeld worden.
Het nadeel van de mysql implementatie is namelijk dat er geen harde limiet (/cq foutmelding ) aan zit. Zonder foutmelding kan je niet zien waarop echt gegroepeerd wordt. Je hebt namelijk nog geen idee of de andere velden unique keys zijn of gewoon undefined waardes zolang je niet in de dbase kijkt.
Het gaat mij hier niet om MySQL, maar om een theoretische optimum voor group by, welke dus ook al is vastgelegd in SQL:2003. Wat MySQL doet is in principe gewoon fout aangezien men zou moeten gaan checken op functionele afhankelijkheden. Dit geven ze zelf ook toe trouwens (je vraagt je af waarom ze dan niet zo'n modus maken, en de huidige default een modus voor snelheid en hacks maken)
Mijn punt is juist dat je dit bijna niet in test-omgeving kan simuleren. Je app kan unique id's afdwingen zolang je dbase dit niet doet blijf je het gat openhouden dat een dba in de toekomst doublures introduceert wat in je app tot onverwachte resultaten kan leiden.
Over het algemeen dwing je dit soort dingen (ook) in de database af, in ieder geval voor primary keys.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
pedorus schreef op zaterdag 07 februari 2009 @ 02:44:
(je vraagt je af waarom ze dan niet zo'n modus maken, en de huidige default een modus voor snelheid en hacks maken)
Geen hond gebruikt SQL_MODE='ONLY_FULL_GROUP_BY', dus nog een modus erbij is, hoewel theoretisch heel leuk, in de praktijk gewoon verspilde moeite, plus dat het zorgt voor weer een rits configs welke in ander gedrag resulteren. Die moeite kan in ieder geval beter gestoken worden in het fixen van de hele SQL_MODE en de b/c policy in het algemeen, want anders wordt er echt nooit op grote schaal vooruitgang geboekt...
Mijn 1e rant incl. link beantwoordt imo gewoon duidelijk je vraag in de quote. :) Alsmede eigenlijk praktisch elke vraag die je over compatibiliteit en mysql kan hebben. :+

{signature}


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Voutloos schreef op zaterdag 07 februari 2009 @ 11:08:
[...]
Geen hond gebruikt SQL_MODE='ONLY_FULL_GROUP_BY', dus nog een modus erbij is ...
Ik zou zeggen dat ONLY_FULL_GROUP_BY dan ook weg kan. Daarnaast heb ik het over een nieuwe default modus, wat er dus voor zorgt dat met de default settings fouten zoals in de TS niet meer gemaakt kunnen worden. Idealiter was sql_mode natuurlijk niet nodig, maar hopelijk helpt het iets om mensen over te krijgen naar nieuwere mysql-versies (doet me denken een beetje denken aan Vista/UAC: sommige mensen gaan niet over als het niet uit kan)...

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten

Pagina: 1