Rapporten met subtotalen

Door Eric Wagener, 15 jaar geleden, 10.627x bekeken

Het maken van rapporten is niet mijn favoriete klusje. Maar helaas moet ik het veel doen en ben altijd op zoek naar manieren om het makkelijker te maken.
De grote uitdaging is dan altijd om de programmatuur leesbaar en onderhoudbaar te houden.

Gesponsorde koppelingen

Inhoudsopgave

  1. Inleiding
  2. Gegevens
  3. Het rapport afdrukken

 

Er zijn 23 reacties op 'Rapporten met subtotalen '

PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
Eric Wagener
Eric Wagener
15 jaar geleden
 
0 +1 -0 -1
Graag commentaar en/of aanvullingen.
Vincent Huisman
Vincent Huisman
15 jaar geleden
 
en waar is de foutafhandeling?
Eric Wagener
Eric Wagener
15 jaar geleden
 
0 +1 -0 -1
Ja de foutafhandeling is inderdaad niet erg zichtbaar hier. Net als het openen van de database, zit dat in $util. Als er iets fout gaat, wordt dat gelogd en bij kritieke fouten wordt er een e-mail verstuurt.

Overigens zou er nog wel een check in moeten of er wel data is opgehaald, anders krijg je alleen een kop te zien. Maar goed, het gaat hier om een testje, dus heb ik dat voor de duidelijkheid maar weggelaten. :-)
Vincent Huisman
Vincent Huisman
15 jaar geleden
 
als je een tutorial maakt moet er ook foutafhandeling in zitten, zo leren anderen dat ook direct goed aan
Eric Wagener
Eric Wagener
15 jaar geleden
 
0 +1 -0 -1
Nee, het is een 'proof of concept', dan hoeft dat niet. Sterker nog, dat zou alleen maar afleiden van het onderwerp.
Anders zou je ook de database moeten normaliseren.
The Force
The Force
15 jaar geleden
 
Ben het met Vincent eens, dit is wel een beginners forum. Als we in alle scripts hameren dat er een goede foutafhandeling in zou moeten zitten dan moet dat hier ook. Een database moet ook goed genormaliseerd zijn. In jouw voorbeeld zou ik overigens het id weghalen en de combinatie van merk en type primary key maken. Is verder goed genormaliseerd hoor ;).
Eric Wagener
Eric Wagener
15 jaar geleden
 
0 +1 -1 -1
OK, laten we voor de discussie er wat dieper op ingaan.
Als je een merk naam en type key maakt, dan is dat niet erg handig. Ik ben van mening dat dit de normaalvorm 0 of 1 is en dat is gewoon niet goed, maar goed genoeg voor het voorbeeld.
Als je bijvoorbeeld de merknaam moet wijzigen, dan moet je dus alle rijen door. En dat is nog maar één reden waarom dit niet goed is. Een id aan een tabel meegeven is de macht der gewoonte. Ik werk normaal met InnoDB en daar is een key zoals jij het voorstelde een heel slecht idee.

Ik ben het met je eens dat normaal gesproken foutmeldingen afgevangen moeten worden. En ja ik zie hier ook veel beginnersvragen.
Maar soms moet je onderscheid maken in een concept en code die je gewoon kunt kopiëren en plakken om het te laten werken.
Als je dat wil, moet je ook consequent zijn en moet het ook echt kunnen werken. Het ontbreken van de foutafhandeling is nog het minste probleem hier. Het openen van de database, is bijvoorbeeld ook best handig om te hebben.

Ik begrijp dat je bij iedereen op het afhandelen van de fouten wordt gelet als het over het forum gaat. Ik zie ook wel dat er vaak wordt geroepen dat er een foutmelding is. Maar in een proof of concept situatie is het gewoon niet handig en zal ik het dus ook nooit doen.

Het is wel een beetje jammer dat er niet op de inhoud van de tutorial ingegaan wordt, want het overbrengen van mijn kennis en ervaring was een beetje het doel van deze actie.
The Force
The Force
15 jaar geleden
 
0 +1 -0 -1
Oké Eric, dan laat je de foutafhandeling eruit. Zo'n probleem vind ik het ook weer niet.

Quote:
Als je een merk naam en type key maakt, dan is dat niet erg handig. Ik ben van mening dat dit de normaalvorm 0 of 1 is en dat is gewoon niet goed, maar goed genoeg voor het voorbeeld.

Dat merk en type primary key zouden moeten zijn maakt het nog niet tot 'normaalvorm 0 of 1'. Dat heeft er niets mee te maken. De key moet liggen op de identificerende kolommen van een rij. In jouw voorbeeld dus de combinatie van merk en type. 'Een (Audi van het type A6) komt (5) keer voor'. Merk + type is het onderwerp, het aantal is aanvullend op dat onderwerp.

Zo even uit mijn hoofd komt het hier op neer. Om in de eerste normaalvorm te staan moet elke tabel een primaire sleutel hebben (een (combinatie van) velden dat een rij uniek identificeert). Dat klopt dus als je merk + type als primary key instelt. Daarnaast moeten alle gegevens atomair zijn. Dat klopt ook in het voorbeeld. Ook moet de volgorde van de rijen in een tabel niet van belang zijn. Dat klopt ook. Om in de tweede normaalvorm te staan moeten alle kolommen die niet de primaire sleutel hebben functioneel afhankelijk zijn van de primaire sleutel. Aantal is functioneel afhankelijk van merk + type. Er wordt namelijk een aantal toegekend aan het type van een bepaalde auto. Daarnaast mag er in een tabel geen redundante data staan. Je zou dus enkel een tabel Merk aan moeten maken. De tabel staat in de derde normaalvorm aangezien er geen transitieve afhankelijkheden bestaan tussen de niet primaire key kolommen.

'The key, the whole key and nothing but the key, so help me Codd'

Quote:
Een id aan een tabel meegeven is de macht der gewoonte.

Dat maakt het nog niet goed. Het merk, het aantal en de type zijn niet functioneel afhankelijk van een nietszeggend cijfer.

Quote:
Ik werk normaal met InnoDB en daar is een key zoals jij het voorstelde een heel slecht idee.

Ik eet mijn schoen op als je een valide reden kan geven waarom het gebruiken van een gecombineerde sleutel in InnoDB een 'heel slecht idee' is. Dat slaat echt nergens op. Wacht dan eet ik beide schoenen op en een winterjas.

Quote:
Het is wel een beetje jammer dat er niet op de inhoud van de tutorial ingegaan wordt, want het overbrengen van mijn kennis en ervaring was een beetje het doel van deze actie.

Tja van de inhoud is verder vrij weinig te zeggen. Moraal van het verhaal is om programmeerwerk 'leesbaar en onderhoudbaar' te houden. Je neemt nu een vrij specifiek voorbeeld en laat zien wat jouw oplossing daarvoor is. Ik kom dat met die subtotalen overigens ook niet al te vaak tegen, maar dat zal wel komen omdat ik een ander soort klanten heb. Misschien heeft iemand anders er wel wat aan.
- SanThe -
- SanThe -
15 jaar geleden
 
De php op de laatste pagina klopt van geen meter. Gebruik bij echo altijd de enkele quotes zodat je de dubbele html-quotes niet hoeft te escapen. Haal $vars altijd buiten de quotes. Zie de kleurtjes.
Eric Wagener
Eric Wagener
15 jaar geleden
 
0 +1 -1 -1
De primary key in een InnoDB tabel wordt op fysieke volgorde gezet. Dus als je daar niet een opvolgend nummer voor neemt, loop je het risico dat een insert een relatief grote hoeveelheid tijd in beslag neemt. In theorie kan het zo zijn dat de hele tabel herschreven moet worden.

Eet smakelijk. :-)

De gegevens staan in NV1 en is daarom voor dit voorbeeld prima, maar dat zou je in het echt nooit doen. Ik zou tenminste een ontwikkelaar onmiddellijk ontslaan als hij/zijn dat wel zou doen. Tenzij er een verdomd goede reden voor is, maar meestal is het alleen maar luiheid (zoals in dit voorbeeld ;-).

En het is Eric, niet Erik.
Eric Wagener
Eric Wagener
15 jaar geleden
 
0 +1 -0 -1
@SanThe
De syntax is prima en de schrijfwijze is vrij normaal. Dat sommige mensen er de voorkeur aan geven met enkele quotes te werken, wil niet zeggen dat er andere mogelijkheden zijn. Het voordeel van dubbele quotes is dat je variabelen direct in je string kunt zetten, zonder dat je de string hoeft te onderbreken. Arrays kun je tussen accolades zetten en als je maar één laag hebt, kun je het zelfs zo gebruiken: '...$rij[test_merk]...'
Hetzelfde geldt overigens voor HereDoc, maar dat heeft niet mijn voorkeur.
Het 'klopt' dus wel, maar het is een andere schrijfwijze en beide zijn goed.
Ik heb het trouwens getest en het werkt perfect.
Vincent Huisman
Vincent Huisman
15 jaar geleden
 
en uiteraard, strings buiten quotes
- SanThe -
- SanThe -
15 jaar geleden
 
Zoals jij het doet is een zeer slordige en onoverzichtelijke manier. Als het zo werkt dan valt dat in mijn visie onder 'toeval'.
Eric Wagener
Eric Wagener
15 jaar geleden
 
LOL, nee dat is echt onzin. Sorry, maar nu moet je echt eerst even de documentatie lezen voor je commentaar geeft.
The Force
The Force
15 jaar geleden
 
Quote:
De primary key in een InnoDB tabel wordt op fysieke volgorde gezet. Dus als je daar niet een opvolgend nummer voor neemt, loop je het risico dat een insert een relatief grote hoeveelheid tijd in beslag neemt. In theorie kan het zo zijn dat de hele tabel herschreven moet worden.

Eet smakelijk. :-)

Daar heb ik nog nooit van gehoord. Kan er ook niets over vinden. Met 'een relatief grote hoeveelheid tijd' bedoel je dat het mogelijk een extra ms kan kosten? Gebruik zelf al jaren logische primary keys i.p.v. nummers en daar heb ik nooit problemen mee gehad. Ik houd de performance van de database bij enkele projecten in de gaten en daar zijn helemaal geen problemen te bekennen. Sterker nog, het is juist een voordeel om je primary key goed te kiezen. Een primary key legt namelijk een clustered index op je gegevens. Dat is de snelste vorm van de indexes. Als je op een grote dataset een select doet en je ordent en/of selecteert op de clustered index dan is dit supersnel aangezien hij niet alle records af hoeft te lopen maar enkel de rijen in een bepaald bereik hoeft te pakken. En dat gaat makkelijk aangezien ze al gesorteerd staan op de primary key. Je zult ook zien dat als je database genormaliseerd is dat je relatief vaak selects doet waar de WHERE/ORDER BY de primary key is. Je wil namelijk vaak gegevens opvragen die te maken hebben met het 'onderwerp' van de rij.

Het is altijd bekend dat InnoDB langzamer is met INSERTS dan met read/writes in vergelijking met bijvoorbeeld ISAM. Dat komt omdat deze veel meer mogelijkheden biedt om de integriteit van de database te bewaken. Daarnaast is InnoDB geoptimaliseerd voor het uitlezen van data. Dankzij het caching mechanisme kan je (met een goedgekozen primary key) veel sneller data ophalen, omdat cache lookups erg snel zijn.

Bij Flickr wordt ook MySQL met InnoDB gebruikt. En als het klopt wat jij zegt dan zouden ze heel snel hun database opnieuw moeten herschrijven en een aantal programmeurs ontslaan. Op http://mihasya.com/blog/innodb-primary-key-clustering-in-action-flickr/ zie je hoe de database administrator van Flickr uitlegt waarom het goed is om geen sequentiële primary keys (lees id's) te gebruiken maar om je primary key goed te kiezen. De performancewinst bij Flickr: meer dan een snelheidsverdubbeling op de 'Photos' tabel (de meest belangrijke tabel van Flickr). Met miljoenen inserts per dag, een gemiddelde van 30 queries per pagina en 12TB aan gegevens in de InnoDB database (http://mike.kruckenberg.com/archives/2007/04/federation_at_flickr_doing_billions_of_queries_a_day.html) lijkt het me dat er toch iets fout zit met je redenatie.

Quote:
En het is Eric, niet Erik.

Sorry!
B a s
B a s
15 jaar geleden
 
Eric, SanThe heeft het over een regel als dit:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
echo '<tr><td>{$rij['test_type']}</td><td>{$rij['test_aantal']}</td></tr>';
?>


Als dat werkt is het in mijn ogen ook toeval. Wat netter is en waaruit je naar mijn mening nog iets kan leren, is het om het als volgt te doen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
echo '<tr><td>' . $rij['test_type'] . '</td><td>' . $rij['test_aantal'] . '</td></tr>';
?>


Variabelen buiten quotes, single quotes bij de array keys en het niet gebruiken van accolades.
Eric Wagener
Eric Wagener
15 jaar geleden
 
Ja Bas, dat weet ik. Heren kom op, het staat gewoon in de documentatie. Als je die niet leest en alleen maar na-aapt wat anderen toevallig ook doen, dan is dat wat mij betreft prima. Maar doe niet net alsof je de wijsheid in pacht hebt.
Ik weet dat de boer niet eet wat hij niet kent, maar dat maakt het eten niet minder goed. En als je de documentatie niet kent of leraar op school dit niet heeft behandeld, dan is dat niet mijn probleem.

Ook InnoDB heeft gewoon documentatie. Lees het en je hoeft anderen niet meer na te praten. Nogmaals, eet smakelijk (graag foto of filmpje van deze actie). Oh wacht je kunt het niet vinden. Hier wordt het in Jip & Janneke taal uitgelegd (sorry, wel in het Engels).

Ik heb trouwens helemaal geen zin een discussie hier te voeren of de code mooi is of niet. Het ging om de functionaliteit van de rapportage en of iemand hier iets aan heeft en/of iets beters weet. Dus niet over geneuzel met accolades.
De code is valide, werkt en heeft niets met 'toeval' te maken. Als je wel roept dat het 'toeval' is, verteld dat meer over je kennis dan over de code.

Mochten jullie nog iets over de functionaliteit hebben dan hoor ik het graag, anders beschouw ik het maar als off topic en verwijs ik graag door naar het forum.
The Force
The Force
15 jaar geleden
 
0 +1 -0 -1
Eric ik ben het met je eens wat betreft de notatie van de strings. Er is niets fout aan de manier waarop jij het doet.

Quote:
Ook InnoDB heeft gewoon documentatie. Lees het en je hoeft anderen niet meer na te praten. Nogmaals, eet smakelijk (graag foto of filmpje van deze actie). Oh wacht je kunt het niet vinden. Hier wordt het in Jip & Janneke taal uitgelegd (sorry, wel in het Engels).

Ten eerste hoef je niet zo denigrerend te doen. Ten tweede praat ik anderen niet na. Wat de documentatie aangeeft (en ja die had ik al gelezen) is dat een lange primary key veel data kan kosten omdat non-clustered indexes naar de hele primary key. Als tip wordt er dan meegegeven dat je kan kiezen voor een auto_increment. Dat is heel wat anders als wat jij hiervoor beweerde:

Quote:
De primary key in een InnoDB tabel wordt op fysieke volgorde gezet. Dus als je daar niet een opvolgend nummer voor neemt, loop je het risico dat een insert een relatief grote hoeveelheid tijd in beslag neemt. In theorie kan het zo zijn dat de hele tabel herschreven moet worden.


Hier heb je ook totaal geen bewijs voor. Dat probleem is nergens gedocumenteerd. Het klopt ook niet. Je gaat daarnaast volledig voorbij aan alle voordelen die het biedt om een logische primary key te hebben. Het praktijkvoorbeeld die ik je gaf met Flickr schuif je ook gewoon aan de kant. Terwijl deze aantoont dat je niet per definitie enkel auto_increment moet gebruiken en dat het juist sneller is om dat niet te doen.

Een ander punt is dat een 'lang' relatief is (!) en dat het een tip betreft die in de performance tuning tips sectie staat. Dus mocht je problemen hebben met de performance en dat wordt veroorzaakt omdat je veel indexes hebt die allemaal moeten verwijzen naar een grote clustered index dan kan je ervoor kiezen om de primary key te verkorten. Als je goed naar je tabel kijkt dan zie je dat er helemaal geen andere indexes liggen op je tabel. Daarnaast heb je met zo'n kleine tabel niet snel last van performance problemen ;).

Als ze zelfs bij Flickr geen problemen hebben met composite primary keys maar er zelfs tijdswinst mee boeken dan lijkt me dat dat enigszins tegen je uitgesproken mening spreekt. Maar je zal vast net als de vorige keren niet inhoudelijk hierop ingaan.

Tot slot maakt een goede primary key de database ook duidelijker. Zeker als je een groot aantal tabellen hebt. Je zal ook minder snel joins moeten doen omdat het onderwerp van een bepaalde tabel in de andere tabel wordt overgenomen als je een foreign key gebruikt. Dan kan je bijvoorbeeld meteen zien dat user 'Henk' een bepaald bericht gepost heeft i.p.v. dat user '183' een bepaald bericht heeft gepost.

Quote:
Ik werk normaal met InnoDB en daar is een key zoals jij het voorstelde een heel slecht idee.

Nee dus!

Quote:
Ik heb trouwens helemaal geen zin een discussie hier te voeren of de code mooi is of niet. Het ging om de functionaliteit van de rapportage en of iemand hier iets aan heeft en/of iets beters weet. Dus niet over geneuzel met accolades.
De code is valide, werkt en heeft niets met 'toeval' te maken. Als je wel roept dat het 'toeval' is, verteld dat meer over je kennis dan over de code.

Mee eens.
Eric Wagener
Eric Wagener
15 jaar geleden
 
0 +1 -1 -1
Je bent echt bang voor die maaltijd hè. :P
InnoDB requires that every table has such an index (also called the clustered index or cluster index), and organizes the table storage based on the column values of the primary key

Ja dus.
Het staat trouwens ook in dat Flickr verhaal van jou. Daar hebben ze het het over performance winst bij de query, niet de insert. En dat klopt ook. Juist omdat de data in de fysieke volgorde van de primary staat, geeft dat een enorme winst bij het zoeken.
The Force
The Force
15 jaar geleden
 
0 +1 -0 -1
Lol Eric kom je nu met de definitie van een primary key aanzetten? Dat heeft niets met de discussie te maken.

Quote:
Je bent echt bang voor die maaltijd hè. :P
InnoDB requires that every table has such an index (also called the clustered index or cluster index), and organizes the table storage based on the column values of the primary key

Ik zal hem even voor je vertalen: 'InnoDB verplicht dat elke tabel een dergelijke index (ook wel de clustered index of cluster index genoemd) heeft, en organiseert de data opslag gebaseerd op de kolomwaardes van de primary key.'

Hier wordt dus enkel gezegd dat je een primary key op een tabel moet zetten en dat de data opgeslagen wordt gebaseerd op de kolomwaardes van de primary key. Dat is juist de reden dat je een logische primary key moet kiezen, zodat de tabel op wat zinnigs is gesorteerd. Dat komt weer ten goede aan de snelheid wanneer je reads doet.

Quote:
Ja dus.

Nee dus. Geef mij dan eens een link in de documentatie die aangeeft dat je geen composite primary key moet gebruiken bij InnoDB. Die is er niet. Het verhaal van Flickr ondersteund dat ook. Geef mij eens een link die aantoont dat inserten zo traag gaat als je een composite primary key gebruikt dat je beter een auto increment id kan gebruiken.

Quote:
Het staat trouwens ook in dat Flickr verhaal van jou. Daar hebben ze het het over performance winst bij de query, niet de insert. En dat klopt ook. Juist omdat de data in de fysieke volgorde van de primary staat, geeft dat een enorme winst bij het zoeken.

Je bent het dus met me eens.
Pim -
Pim -
15 jaar geleden
 
1 +1 -0 -1
Misschien is het leuk om deze discussie op het forum voort te zetten?
Eric Wagener
Eric Wagener
15 jaar geleden
 
De data wordt op de volgorde van de primary key gezet en daardoor kan een insert langer duren. Dat is wat ik van het begin af heb gezegd (scroll omhoog en lees nog maar een keer).

Een insert is iets anders dan het lezen van de data, maar dat hoef ik jou niet uit te leggen. Ik heb het nooit over een trage select query gehad.

Het is trouwens niet een beschrijving van 'een' PK, maar de omschrijving van de PK binnen InnoDB.

Je haalt wel meer zaken door elkaar trouwens, dat ontslaan sloeg op NV1 en niet op de PK.
Best lastig dat lezen.

Maar Pim heeft gelijk, je gaat je ongelijk toch niet toegeven en je bent alleen maar andere rookgordijnen aan het opzetten om gelijk te krijgen.

Dus sluit ik graag af met nog een vraag: Als ik je gelijk geef, hou je dan op?
PHP hulp
PHP hulp
0 seconden vanaf nu
 

Gesponsorde koppelingen
The Force
The Force
15 jaar geleden
 
Mijn laatste reactie, want ik houd het niet zo van op de man spelen.

Quote:
De data wordt op de volgorde van de primary key gezet en daardoor kan een insert langer duren. Dat is wat ik van het begin af heb gezegd (scroll omhoog en lees nog maar een keer).

Je hebt nergens bewijs gegeven die aantoont dat het zo'n probleem zou zijn dat inserten dat je geen composite primary keys zou moeten gebruiken. Je komt met van alles aanzetten wat niet klopt. 'Ik werk normaal met InnoDB en daar is een key zoals jij het voorstelde een heel slecht idee.'. Je komt met de uitleg wat een primary key inhoudt om je 'punt' te bewijzen. Klopt dat je eerder al over die inserts bent begonnen en ik heb je ook gevraagd om dat te onderbouwen met bronmateriaal. Dat doe je niet want dat kan je niet.

Quote:
De primary key in een InnoDB tabel wordt op fysieke volgorde gezet. Dus als je daar niet een opvolgend nummer voor neemt, loop je het risico dat een insert een relatief grote hoeveelheid tijd in beslag neemt. In theorie kan het zo zijn dat de hele tabel herschreven moet worden.

Niet bewezen onzin dus.

Quote:
Het is trouwens niet een beschrijving van 'een' PK, maar de omschrijving van de PK binnen InnoDB.

Goh dat staat in de quote. Mierenneuken is ook een kunst op zich.

Quote:
Je haalt wel meer zaken door elkaar trouwens, dat ontslaan sloeg op NV1 en niet op de PK.
Best lastig dat lezen.

Ik ben helemaal niet ingegaan op dat jij mensen zou ontslaan als het niet goed genormaliseerd zou zijn.

Quote:
Maar Pim heeft gelijk, je gaat je ongelijk toch niet toegeven en je bent alleen maar andere rookgordijnen aan het opzetten om gelijk te krijgen.

Misschien moet je de moeite nemen om zijn reactie door te lezen.

Quote:
Dus sluit ik graag af met nog een vraag: Als ik je gelijk geef, hou je dan op?

Ik had je hoger ingeschat.

Om te reageren heb je een account nodig en je moet ingelogd zijn.

Inhoudsopgave

  1. Inleiding
  2. Gegevens
  3. Het rapport afdrukken

Labels

PHP tutorial opties

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.