AnaXyd Skrevet 12. januar 2008 Skrevet 12. januar 2008 Heisann! Har en database med forskjellige kunder som jeg vil telle opp. Fant scriptet under på nett, men jeg sliter litt med det. Er sikkert ikke store problemet jeg gjør, men jeg finner rett og slett ikke ut av det. Det som kommer ut av scriptet nå, er "Det er 1 kunder.". Men dette er feil, for det er rundt 50 kunder i databasen, som den ikke teller med. fname = fornavn _databasen_ = databasen jeg bruker. Har valgt å sensurere denne. kundenr = kundenummer <?php // Make a MySQL Connection $query = "SELECT fname, COUNT(fname) FROM _databasen_ GROUP BY kundenr"; $result = mysql_query($query) or die(mysql_error()); // Print out result while($row = mysql_fetch_array($result)){ echo "Det er ". $row['COUNT(fname)'] ." kunder."; echo "<br />"; } Hva gjør jeg feil? Hvordan skal jeg få denne til å telle alle kundene i fname?
Ernie Skrevet 12. januar 2008 Skrevet 12. januar 2008 (endret) Det går ikke an å gjøre det slik du gjør (d'oh). Det du gjør feil er at du vil hente ut alle radene og samtidig få med deg antall rader. Korrekt? Isåfall fjerner du COUNT(fname) siden det ikke vil fungere. I stedet kan du bruke mysql_num_rows(...). Red.: Skal du bare ha ut antall kunder kan du bruke følgende spørring: SELECT COUNT(*) FROM table Endret 12. januar 2008 av Ernie
AnaXyd Skrevet 12. januar 2008 Forfatter Skrevet 12. januar 2008 Aha, så kanskje på et litt feil eksempel jeg da... Skal prøve nå, og se om det funker!
AnaXyd Skrevet 12. januar 2008 Forfatter Skrevet 12. januar 2008 (endret) Dette blir feil, eller? <?php // Make a MySQL Connection $query = "SELECT COUNT(*) FROM _database_"; $result = mysql_query($query) or die(mysql_error()); // Print out result while($row = mysql_fetch_array($result)){ echo "Det er ". $result ." kunder."; echo "<br />"; }?> Det kommer nemlig bare ut "Det er Resource id #5 kunder." Endret 12. januar 2008 av AnaXyd
Gjest Slettet+142 Skrevet 12. januar 2008 Skrevet 12. januar 2008 <?php // Make a MySQL Connection $query = "SELECT COUNT(*) FROM _database_"; $result = mysql_query($query) or die(mysql_error()); // Print out result $row = mysql_fetch_array($result); echo "Det er ". $row[0] ." kunder."; echo "<br />"; ?>
AnaXyd Skrevet 12. januar 2008 Forfatter Skrevet 12. januar 2008 Aha! Det var det feilen lå ja.. Hvorfor $row[0] egentig? For at denne er default, eller standardverdi?
Ernie Skrevet 12. januar 2008 Skrevet 12. januar 2008 Aha! Det var det feilen lå ja.. Hvorfor $row[0] egentig? For at denne er default, eller standardverdi? Fordi det er 1. felt returnert i raden.
AnaXyd Skrevet 12. januar 2008 Forfatter Skrevet 12. januar 2008 Okay.. Måtte bare prøve å lære av mine feil.. Takk for hjelpen karer!
grimjoey Skrevet 12. januar 2008 Skrevet 12. januar 2008 bruk print_r til å se arrayer når du utvikler. hadde du kun brukt $row ville du fått "Det er Array kunder!" en print_r ville vist deg at $row så slik ut: Array ( [0] -> 51 ) (dersom var 51 rader i tabellen din) derfor må du bruke $row[0] for å hente ut antallet. gjør du for eksempel: $res = mysql_query('select id, brukernavn, epost from brukere;'); $row = mysql_fetch_row($res); ville $row vært noe liknende: Array ( [0] -> 1 [1] -> AnaXyd [2] -> [email protected] ) gjør du $row = mysql_fetch_row($res); en gang til vil du få et liknende array med info fra neste bruker. mysql_fetch_assoc() gjør det samme, bortsett fra at den returnerer et navn assosiert array, med feltnavnene som navn liknende: Array ( ['id'] -> 1 ['brukernavn'] -> AnaXyd ['epost'] -> [email protected] )
AnaXyd Skrevet 12. januar 2008 Forfatter Skrevet 12. januar 2008 Aha, ble litt mer forståelig nå.. Takk for grundig forklaring! Kom på en ting til: Er det mulig å telle opp hvor mange som kunder som har betalt? Hvis jeg har en kolonne som heter "Betalt?", og innholdet i radene er enten ja eller nei. Kan den telle hvor mange som har "ja" i seg?
Ernie Skrevet 12. januar 2008 Skrevet 12. januar 2008 Ja, jeg tror det bare skal være å slenge på en WHERE i SQL-spørringen. Altså SELECT COUNT(*) FROM table WHERE field = 'value'
grimjoey Skrevet 12. januar 2008 Skrevet 12. januar 2008 feltet betalt bør være av typen BIT(1) DEFAULT NULL og være 1 for de som har betalt. BIT(1) bruker max 1 bit med plass i databasen VARCHAR(3) (som du trenger for ja og nei) bruker max 3*8 = 24 bit dette ganger du opp med radene for å få totalen. kanskje ubetydelig for 50 rader, men har du 250 000 rader for eksempel kan dette ha en del å si på hastighet osv. select count(kundenr) from _databasen_ where betalt = 1;
AnaXyd Skrevet 12. januar 2008 Forfatter Skrevet 12. januar 2008 Ja, jeg tror det bare skal være å slenge på en WHERE i SQL-spørringen. Altså SELECT COUNT(*) FROM table WHERE field = 'value' Denne fungerte utmerket.. Takk! Koden: <?php $query = "SELECT COUNT(*) FROM _database_ WHERE betalt = 'Ja'"; $result = mysql_query($query) or die(mysql_error()); // Print out result $row = mysql_fetch_array($result); echo "<p>Antall betalende: ". $row[0] ." stk.</p>"; echo "<br />"; ?> feltet betalt bør være av typen BIT(1) DEFAULT NULL og være 1 for de som har betalt. BIT(1) bruker max 1 bit med plass i databasen VARCHAR(3) (som du trenger for ja og nei) bruker max 3*8 = 24 bit dette ganger du opp med radene for å få totalen. kanskje ubetydelig for 50 rader, men har du 250 000 rader for eksempel kan dette ha en del å si på hastighet osv. select count(kundenr) from _databasen_ where betalt = 1; Denne skjønte jeg ikke helt? Dette er en bedre måte å løse det på, om det er flere kunder? Så hvis det er 250 000 kunder, kan det ta uhorvelig lang tid med koden jeg har benyttet nå?
grimjoey Skrevet 12. januar 2008 Skrevet 12. januar 2008 (endret) nei. det ville ikke ta veldig lang tid. litt avhengig av trafikk, kunne du fått et lite problem. men tenk sider som mail.google.com og www.facebook.com som har milioner av brukere og milliarder av database rader for diverse ting. de er avhengig av å spare inn der det er mulig. så det er like greit å gjøre det en vane å forsøke å skrive så effektivt som mulig. du har en tabell med rader av informasjon (brukere) og du ønsker et nytt felt som forteller om status på en bruker er betalt eller ikke betalt. her er det to muligheter. ja (betalt) eller nei (ikke betalt). den mest effektive måten er å lage et felt av typen bit med lengde 1, altså BIT(1) dette feltet kan være 0 eller 1. det gjør det samme som nei eller ja, men det bruker kun 1 bit på å gjøre det. en bokstav er vanligvis 1 byte (det finnes mange unntak. UTF-8 kan ha et enkelt tegn på opp til 4 bytes). 1 byte er 8 bit. så man kan lagre betaling status til 8 brukere i en bokstav med andre ord. ordet "nei" som betalt status for en bruker krever like mye plass som betalt status på 24 brukere dersom bit(1) hadde blitt brukt. bruker du tekst for å vite om en rad har betalt eller ikke bruker du unødig plass. spiller sikkert ingen rolle for ditt bruk. Endret 12. januar 2008 av grimjoey
AnaXyd Skrevet 12. januar 2008 Forfatter Skrevet 12. januar 2008 Skjønner... Kanskje jeg skal prøve å gjøre som ditt eksempel med det samme, slik at jeg lærer meg å skrive mest effektiv kode som mulig.. Uansett skal du ha takk som gidder å skrive så grundige innlegg! Takk for hjelpen!
Ernie Skrevet 12. januar 2008 Skrevet 12. januar 2008 (endret) grimjoey: Jeg synes du er en smule paranoid her. Jeg påstår overhode ikke at jeg er noen database-guru, heller tvert imot. Dog, at 1 bit kontra 3 byte pr. rad skal ha noen betydningsfullt utslag på ytelsen er helt på jordet for meg. Ut fra min kunnskap har diskforbruk ytterst lite å si i forhold til indekser og korrekt bruk av de. I tillegg er det vel en fordel å få indeks inn i minnet også. Jeg vil tro at innen 1 bit vs. 3byte for en effekt på ytelsen har man allerede fått ytelsesproblemer grunnet helt andre ting, men det er såklart mulig tar feil der. PS: BIT er før MySQL 5.0.3 et alias for TINYINT(1), og tar da 1 byte. Red.: Misforstå meg rett. Jeg er forsåvidt enig i at bit er bedre enn å ha et char/varchar felt for det, men å argumentere med at bit gir bedre ytelse blir for meg veldig uten rot i virkeligheten. Personlig ville jeg vel gått for enum da det er mer logisk enn å bruke *int eller bit. Endret 12. januar 2008 av Ernie
grimjoey Skrevet 12. januar 2008 Skrevet 12. januar 2008 Ernie: det er mest prinsippet jeg vil fremheve. ikke bruke LONGBLOB for å lagre en id liksom. det kan være nyttig å påpeke slike ting som dette for brukere som ikke er noe særlig oppmerksomme på datatyper. kan få de til å lære seg litt om det dersom de er interesert, og det vil føre til bedre databaser. kan ikke du fortelle litt om indekser? for der er jeg ganske blank.
Ernie Skrevet 12. januar 2008 Skrevet 12. januar 2008 (endret) Som sagt er jeg ikke akkurat noen database-guru, men her er nå greia: Uten indekser må man gå igjennom hele tabellen for å hente ut rader, og naturlig nok blir det ganske treigt etterhvert. For å bøte på det kan man lage indekser over tabellen. Disse kan gjøres over en eller flere felter og fungerer som en oppslagstabell over radene. Hvis du nå har en indeks på felt1 og kjører spørringen "SELECT * FROM tabell WHERE felt1 = 'verdi'" vil man kunne slippe å gå igjennom hele tabellen, som kan være veldig stor, og i stedet gå igjennom indeksen som er mye mindre. Her vil man da finne de radene som har felt1 med verdien 'verdi'. Disse vil så referere til plasseringer i tabellen. Nå vil noen fort tro at det bare er å sette en indeks på alle mulige felter og kombinasjoner av de, men fult så enkelt er det ikke. Ulempen med indekser er blant annet at operasjoner som INSERT og DELETE blir tregere siden man i tillegg til å måtte vedlikeholde tabellen også må vedlikeholde x antall indekser. Videre er det heller ikke sånn at man alltid har nytte av flere indekser siden man til enhver tid bare kan velge en indeks (iallfall i MySQL). Med andre ord er det med indekser en balansegang mellom hva du trenger og har nytte av både i praksis og i forhold til ytelse. En ting man bør legge merke til er at primærnøkler og fremmednøkler er indekser. I tillegg er EXPLAIN nyttig i forhold til å finne ut hvilken indeks man har tilgjengelig og hvilken MySQL bruker i en SQL-spørring. Sånn i forhold til ytelse og optimalisering av mysql-tabeller og spørringer så er dokumentasjonen for mysql et fint sted å starte. Red.: Bare for å ha sagt det: Det er ingen fasit på når man skal og ikke skal bruke indekser. Riktignok kan man som hovedregel sette indeks på felter man bruker i en JOIN, men med riktig oppsett er dette primærnøkler og fremmednøkler (hvis man ikke bruker MyISAM da selvsagt). Endret 12. januar 2008 av Ernie
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå