Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: MySQL ongelma

Sivun loppuun

apocalypse [31.08.2004 19:08:10]

#

Elikkää kaverin mukaan alla oleva koodipätkä pitäisi toimia, mutta mutta =P
Koodin olisi tarkoitus hakea tietokannasta id'n arvo ja pistää arvoon yksi lisää (+1). Tietokannasa on seuraavat taulukot; id, username, password, email, validate.
Niin ja tietokannan nimi on siis an_member.

Edit: Asia josta errori tulee on rivi jolla $id++ on...

$id=mysql_result(mysql_query("SELECT COUNT(*)  FROM an_member"))
$id++

Antti Laaksonen [31.08.2004 19:17:14]

#

Virheen syynä on varmaan se, että et ole pannut puolipistettä rivin loppuun. Kaverisi koodi laskee taulun rivien määrän, eli jos id-numerot ovat järjestyksessä ja numerointi on aloitettu ykkösestä, tuloksena tosiaan on suurin id-numero. Varmempi tapa suurimman id-numeron selvitykseen olisi tosin kysely:

SELECT MAX(id) FROM an_member

Onko tarkoituksena, että joka rivillä on oma id-numero? MySQL sisältää tähän myös valmiin AutoIncrement-ominaisuuden, jota käyttämällä id-numerosta ei tarvitse huolehtia itse, vaan jokainen tauluun lisättävä rivi saa suoraan seuraavan järjestyksessä olevan numeron.

ajv [31.08.2004 19:18:19]

#

En mene sanomaan tuosta tavasta muuta kuin, että jos toimisikin, niin toteutus olisi purkka. Jos taulusta on poistettu rivejä, niin tuo kusee.

$sql =  mysql_query("SELECT MAX(id) as id FROM an_member");
$id = $mysql_fetch_array($sql);
$id = $id['id']++;

Ihan mielenkiinnosta, miksi haluat tietää seuraavan vapaan id:n?

Edit:Antti oli nopsempi :(

Wizard [31.08.2004 19:55:18]

#

Käytännössä AutoIncrement arvoa ei kannattaisi käyttää jos vain softan koodaaja jaksaa tehdä rutiinin siihen, että kasvattaisi arvoa aina ohjelmallisesti tai etsisi vapaan ID arvon.

Mutta ohjelmoijien laiskuus tarkoittaa automaattisen ID arvon kasvattamista SQL -palvelimen päässä... SQL palvelimien ylläpitäjien keskuudessa tästä on paljonkin puhuttu.

apocalypse [31.08.2004 20:13:40]

#

Kokeilin ajvn koodia mutta tuloksena on vain kasa erroreita. :P
poistettuani koodista $id = $mysql_fetch_array($sql); koodi toimii mutta tulostaa kuitenkin errorin.

Warning: mysql_query(): Access denied for user: 'www-data@localhost' (Using password: NO) in /home/****/public_html/add.php on line 19

Warning: mysql_query(): A link to the server could not be established in /home/****/public_html/add.php on line 19

www-data ei ole käyttäjä joten mikä ihme se on? :P
"A link to the server could not be established" Kuitenkin taulukkoon on tullut uusi käyttäjä.
Jossain kusee mutta missä :/

Edit: Tarkemmin katsottuna $id = $mysql_fetch_array($sql); poisto ei ehkä ollut niin ovelaa :P
Tosin sen lisääminen lopettaa ohjelman toiminnan kokonaan...

Edit2: Minulla on kyllä kaikki salasanat yms että mysql pitäisi toimia joten älkää kysykö sitä... :P

Antti Laaksonen [31.08.2004 20:30:57]

#

Wizard kirjoitti:

Käytännössä AutoIncrement arvoa ei kannattaisi käyttää jos vain softan koodaaja jaksaa tehdä rutiinin siihen, että kasvattaisi arvoa aina ohjelmallisesti tai etsisi vapaan ID arvon.

Minkä takia varta vasten tarkoitukseen suunniteltua toimintoa ei pitäisi käyttää? Tietenkin uuden id-numeron voi laskea ihan hyvin myös skriptissä. Mutta jos sattumalta useampi käyttäjä meinaa lisätä samaan aikaan riviä, voi käydä niin, että niille tulee erehdyksessä sama tunnus.

apocalypse [31.08.2004 20:36:01]

#

ihan tyhmyyttäni kyselen, miten mahtaa moinen autoincreament toimia?

Valmis koodipätkä ei olisi pahitteeksi :O

Edit: phpMyAdminista löytyi jotain kiintoisa....

ajv [31.08.2004 20:37:31]

#

apocalypse kirjoitti:

Kokeilin ajvn koodia mutta tuloksena on vain kasa erroreita. :P
poistettuani koodista $id = $mysql_fetch_array($sql); koodi toimii mutta tulostaa kuitenkin errorin.

Äh, sinne oli tullu pieni typo tohon koodiin. Tietenkään mysql_fetch_array():n edessä ei pidä olla "$"-merkkiä...

Joo ja hieman kanssa ihmetyttää, miksi autoincrementin käyttö muka ei olisi suotavaa? Wizard tietysti taas tarkoittaa jotain 150 tuhannen käyttäjän tuntikävijämääriä, joista jokainen lataa 10 sivua sekunnissa ja joissa jokaisessa latauksessa rasitetaan tietokantaa 10 kertaa. Mutta luulisi silti rasittavan enemmän se, että ensin kysytään tietokannalta mikä se suurin id on ja sitten vasta lisätään data...

Wizard [31.08.2004 21:16:15]

#

1) Relaatiotietokannoissa jos ja kun päivitetään useampia tauluja samaan aikaan, niin autoincrement arvot aiheuttavat joskus hieman päänvaivaa.

2) Sitten ne palvelinrykelmät joissa tietoa päivitetään useiden palvelinten kesken, niin sielläkin autoincrement arvot hiemat aiheuttavat päänvaivaa. Tämä on SQL -palvelin kohtaista.

3) Viiteavaimet aiheuttavat myös hieman hankaluuksia kun tuhotaan toisesta taulusta tietoa, mutta toisesta halutaan nollata vain kenttä (jossa laskuri/autoincrement käytössä). Jos kyseessä on vielä kenttä jossa on perusavain (primary key), niin näkemiin...


4) Autoincrement arvo esim. MySQL:ssä tarvitsee AINA indeksin. Tunnetusti index hidastaa palvelimen vauhtia INSERT, UPDATE ja DELETE toiminnoissa. SELECT onkin sitten eri asia. Tämä on 'monipiippuinen' asia joka on hyvinkin riippuvainen tietokannasta, suorituskyvystä ja softasta joka tietokantaa käyttää.

5) Muistaakseni esim. MySQL käytti jossain vaiheessa autoincrement kentän muodostamiseen SQL käskyä select max(kentta)...

Kohdat 1 & 2 ovat ongelmia joihin törmää kun on enemmän dataa ja rautaa verkossa. Kohdat 3 & 4 ovatkin jo sellaisia mihin törmää ihan ns. 'normaalissa elämässä'. 5 kohta menee hieman ulkomuistista joka ei ole ihan paras kaikissa tilanteissa. Käytännössä laskuria (=autoincrement) ei kannata käyttää jos perusavaimena voidaan käyttää jotain sellaista mikä on takuulla uniikki arvo. Tässä siis korostuu se, että kuinka hyvin osataan suunnitella relaatiotietokanta.


Esimerkiksi alkuperäisessä viestissä ID -kenttä on täysin tarpeeton, koska usernamen pitäisi olla uniikki jo sellaisenaan.

Tyydyttikö?

ajv [31.08.2004 21:29:15]

#

Ja minun pitäisi ottaa nuo huomioon suunnitellessani vieraskirjaa? Kuten jo vihjasin, varmasti jossakin suuressa yrityksen tietokannassa tuolla on merkitystä, mutta kuinka monessa ns. "normaalikokoisessa" webbisovelluksessa tuo autoincrement kannattaa kiertää? Enkä tarkoita "normaalikokoisella" mitään googlen tietokantaa, vaan esimerkiksi putkan foorumin tietokantaa.

Wizard [31.08.2004 21:43:39]

#

Putkassa pätee varmasti relaatiomalli- sekä eheyssäännöt siinä missä muuallakin. En näe Putkaa mitenkään erityisenä tapauksena.

Itse mietin jo hyvin tarkkaan, että tarvitaanko laskuri tyyppistä kenttää ollenkaan. Sitä käytetään ehdottomasti liian paljon jo nykyisin kuten tuossa jo aikaisemmin viittasin alkuperäiseen viestiin.

Eli parempi kysymys on se, että miksi ylipäätään käytetään laskuri tyyppisiä kenttiä, koska ne eivät ole läheskään aina edes tarpeellisia?

Myönnän toki, että laskuri tyyppinen kenttä on ehdottomasti erittäin kätevä, mutta kun sitä ei aina tarvita. Sen kätevyys onkin tehnyt siitä ns. 'liian käytetyn' eikä asioita aina mietitä ihan loppuun asti.


Edit: SQL lauseessa voidaan myös laskea itse kyseinen uusi ID arvo, eikä ole edes vaikeaa. Mutta tietyissä asioissa ei varmaan kannata kiistellä: laskuri on erittäin kätevä joissakin tilanteissa, kyllä minä sen myönnän.

renni [04.09.2004 10:34:43]

#

Ei pidä myöskään sekoittaa laskurikentää ja id-kenttää.

apocalypse [04.09.2004 10:55:52]

#

Tarvitsin ID-kenttää käyttäjän rekisteröintiin jotta jokainen käyttäjä saa oman ID'n mutta ratkaisin ongelman antamalla ID'n rand(0,99999)*(0,99999) luvuista. Tokin on mahdollista että kaksi saavat saman ID'n mutta hyvin epätodennäköistä...

ajv [04.09.2004 11:11:37]

#

apocalypse kirjoitti:

Tokin on mahdollista että kaksi saavat saman ID'n mutta hyvin epätodennäköistä...

Luin juuri pikkumyyn kirjoittaman artikkelin ja ja häntä lainaten:
"pienikin mahdollisuus on huomattavasti suurempi kuin täysi mahdottomuus"
Suosittlen todellakin ottamaan tuon auto_increment-kentän käyttöön. Seuraava lause vaihtaa id-kenttäsi auto_incrementiksi:

ALTER TABLE taulunnimi CHANGE id id INT AUTO_INCREMENT

Tämän jälkeen voit poistaa kaikista INSERT-lauseistasi sen id:n lisäämisen, sillä mysql huolehtii siitä puolestasi.

raezel [04.09.2004 19:57:14]

#

Kyllä itsetehty skripti on monesti kätevämpi. Varsinkin Oraclea käyttäessä mitään autoincrement toimintoa ei edes ole. Ja itsetehdyllä skriptillä saa myös välissä olevat tyhjät käyttöön. Kätevää jos kannasta poistetaan usein jotain. Koska väliin jää muuten suuri määrä tyhjiä id arvoja.

ajv [04.09.2004 22:03:20]

#

raezel kirjoitti:

Kyllä itsetehty skripti on monesti kätevämpi.

Noh, en suoranaisesti väitä vastaan, mutta näköjään myös monesti huonompikin. Mitä apocalypse tässä nyt on tuon skriptinsä kanssa kikkaillut, niin aluksi hän yritti tehdä _täsmälleen_ saman manuaalisesti, kun mitä auto_increment tekee. Ja kun ei saanut toimimaan, niin keksi purkan: arpoo jokaiselle käyttäjälle oman id ilman tarkistuksia. Jos jompi kumpi näistä systeemeistä on parempi kuin auto_increment, niin olisi kiva kuulla perusteluja.

Eli jos ei ole taitoa koodata pätevää systeemiä korvaamaan tuota, niin on ehkä parempi käyttää valmista.

renni [05.09.2004 14:27:48]

#

ID-kenttä kannattaa myös määritellä unique:ksi, ei taatusti löydy kahta samaa arvoa sitten.

Väleissä olevista tyhjistä arvoista ei kannata piitata.

Autoincrement tai vastaava on ihan näppärä keino ID:n luomiseen, useimmiten jopa paras.

raezel [05.09.2004 18:55:04]

#

Jouduin tosiaan tekemään skriptin itse käyttäessäni Oraclea jossa moista ei ole.

$palautenro = 1;

//annetaan palautenumero
while(OCIFetchInto($stmt, $values))
{
  //haetaan tieto muuttujaan
  $numero = OCIResult($stmt, "PALAUTENRO");

  //jos numero jo olemassa, otetaan seuraava
	if($palautenro == $numero)
	{
	  $palautenro = $palautenro + 1;
	}
}

saattaa olla hivenen purkka(ja jollakulla löytyy varmasti sanomista), mutta ainakin toimii.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta