[ slobytox @ 07.11.2006. 18:44 ] @
Molim za savet, kako biste vi reseili sledeci problem:

Imam recimo tabelu t1 i u njoj polja p1, p2 itd.
p1 je primarni kljuc (auto_increment) biginit(20)
p2 je samo biginit(20)

Hocu jednom sql naredbom da izvrsim insert u tu tabelu ali da se u p2 upise vrednost koja ce biti upisana i u p1 (formirana auto_increment-om)
Naravno od izuzetne je vaznosti da resenje bude potpuno pouzdano i u situaciji da istu bazu koristi 100 operatera i da recimo u istom trenutku ima 40-ak konekcija.

Ne mogu p2 podesiti da bude auto_increment jer prilikom update-a drugacije obradjujem podatke u p2 (u suprotnom naravno p2 i ne bi imalo smisla da egzistira).

Mislim da problem potice odatle st mysql poslednje upisuje p1 polje i tada mu i formira vrednost tako da uopste ne znam kako ovo da resim a da bude brzo i pouzdano.

Pozdrav,
SJ
[ zmau @ 08.11.2006. 00:33 ] @
Vidi funkciju LAST_INSERT_ID(). U helpu piše između ostalog The ID that was generated is maintained in the server on a per-connection basis

Znači, biće nešto kao
Code:

insert into tabela(p2) values (0);
update tabela set p2 = p1
where p1 = LAST_INSERT_ID();

i to je to.
[ slobytox @ 08.11.2006. 15:14 ] @
Znam za to ali u toj varijanti procesoru treba vise nego duplo vremena u poredjenju sa varijantom da problem resim samo jednom insert komandom.
Pored toga ja mysql-u pristupam preko PHP-a tako da je on klijent za mysql. Za svakog usera (operatera) imam poseban username i password u mysql-u i za svakog se formira prakticno posebna konekcija ali ne koristim permanentne konekcije. To moze da zakomplikuje primenu ovog resenja i da ga ucini nepouzdanim.

Da li postoji neko elegantnije i pouzdanije resenje????
[ shketuljko @ 08.11.2006. 16:45 ] @
Pod pretpostavkom da pricamo o autoincrementu
ja bih ovako uradio:


Code:
SELECT max( `id2` ) from `tbl`
Rezultat povecao za 1 i odradio insert:

INSERT INTO `tbl` (`id2`) values (rezultat);



Trosenje resursa je smanjeno u odnosu na insert pa update!!!
[ slobytox @ 08.11.2006. 16:56 ] @
Jeste manje trosenje resursa ali kada je baza opterecena velikim brojem unosa moze se desiti da izmedju komandi select i insert protrci insert od drugog usera (druga konekcija) i to bi bio kraj price za bazu.
Ne mogu da verujem da za ovaj problem ne postoji neko elegantno resenje?
[ Zmaj @ 08.11.2006. 17:34 ] @
zasto se opterecujes sa tako banalnim stvarima, koliko se cesto taj upit desava da bi ti bila potrebna takva optimizacija, jednostavno uradi query insert uzmes last id sa mysql_insert_id(); i ubacis ga u drugi query. zasto ti ovo nije dovoljno elegantno. I nemoj da brines o procesoru, i njegovom vremenu, stavi u kod deo sto meri vreme, pa ces videti sta ti je ciniti. ali opet ti kazem lupas glavu oko nepotrebnih stvari
[ shketuljko @ 08.11.2006. 17:46 ] @
Ako oces da se osiguras pokreni transakciju i iskombinuj nesto!
Tako ces biti siguran da je upit prosao (vise upita)

I ja se slazem da mozda ne treba da lupas glavu jer mislim da vrijeme potroseno ne moze biti veliko, ali sam siguran da update vuce vise vremena nego select
[ zikaa @ 09.11.2006. 09:25 ] @
a da pokusas da simuliras auto_increment vrednost
Code:
 insert into tabela (id1,id2)  (select max(id1)+1, max(id1)+1 from tabela) 
[ slobytox @ 09.11.2006. 14:33 ] @
Citat:
Zmaj: zasto se opterecujes sa tako banalnim stvarima, koliko se cesto taj upit desava da bi ti bila potrebna takva optimizacija, jednostavno uradi query insert uzmes last id sa mysql_insert_id(); i ubacis ga u drugi query. zasto ti ovo nije dovoljno elegantno. I nemoj da brines o procesoru, i njegovom vremenu, stavi u kod deo sto meri vreme, pa ces videti sta ti je ciniti. ali opet ti kazem lupas glavu oko nepotrebnih stvari


Desava se prilikom svakog unosa u bazu ili izmene podataka (oko 100000 puta dnevno). Upit je posledica koncepcije programa i to mogu ali ne zelim da menjam jer bih izgubio deo funkcionalnosti koji smatram veoma vaznim.
To je siroka tema da bismo je ukljucili u diskusiju o MySQL-u. Ja sam se ovde fokusirao na konkretnu potrebu i nacin kako to realizovati u MySQL-u.

Ja to trenutno radim tako sto upisem pa izvrsim update ali zeleo bih da znam da li je moguce ikako to uraditi jednom naredbom a da pri tome bude potpuno pouzdano.
Ovo jeste pravo pitanje za MySQL support ali kad se nema para ....

Citat:
zikaa: a da pokusas da simuliras auto_increment vrednost
Code:
 insert into tabela (id1,id2)  (select max(id1)+1, max(id1)+1 from tabela) 


Nesigurno nemam garancije da preko druge konekcije nece protrcati drugi insert izmedju izvrsenja podupita i inserta.
[ slobytox @ 09.11.2006. 14:42 ] @
Zaboravih da kazem da je baza skoro 2GB i imajuci u vidu hardware i opterecenje svaki detalj postaje vazan sto se tice optimizacije (vecina upita se korektno izvrsava ali pojedini nesto malo slozeniji se izvrsavaju i vise od 60 sec a upiti za statistiku i analitiku traju po nekoliko minuta).
Bez obzira na to za sada sam zadovoljan radom MySQL-a i u poredjenju sa SQL-serverom radi brze.
Baza se inace vrlo frekventno koristi (skoro 2 miliona upita dnevno tako da je to dodatno ogranicenje).
[ Zmaj @ 09.11.2006. 15:57 ] @
onda pogledaj transakcije, zapocnes transakciju uradiste upite i zavrsis transakciju, to tije sigurno i server odradjuje upise tek kad zavrsis transakciju
[ slobytox @ 10.11.2006. 21:31 ] @
Citat:
Zmaj: onda pogledaj transakcije, zapocnes transakciju uradiste upite i zavrsis transakciju, to tije sigurno i server odradjuje upise tek kad zavrsis transakciju


Dobro a sta se desava sa ostalim userima koji preko drugih konekcija pokusavaju u istom treutku da odrade upis u istu tabelu. Da li transakcija zakljucava tabelu za sve sem za konekciju koja je pokrenula transakciju ili samo testira unos i potvrdjuje ukoliko je sve u redu odnosno vraca na staro ako ima problema???
Ukoliko zakljucava tabelu onda je to ujedno i najsporiji nacin jer su ostali na cekanju, update je u tom slucaju brzi.
[ Zmaj @ 11.11.2006. 14:37 ] @
pogledaj ovo na
http://dev.mysql.com/books/mysqlpress/mysql-tutorial/ch10.html

to je prica o transakcijama u mysql.

nadam se da sam ti pomogao, posto dosad nisam imao potrebe za transakcjama, nemogu da ti prenesem licna iskustva. izmeri vreme potrebno za izvrsavanje nekog upita pa ces doci do opipljivih rezultata, i ono sto je sporo mozda je dovoljno za tvoje potrebe od 100.000 upisa dnevno
[ Dejan Topalovic @ 15.11.2006. 16:51 ] @
Hm, nije mi jasno zasto bi tako radio, ako kazes da tu vrijednost kasnije tako i tako mijenjas prilikom updatea...
Ako ti ta vrijednost treba za neko izracunavanje prije updatea, onda koristi SELECT IFNULL(p2, p1) i gotova prica, jer ti je samo p1 referenca pri SELECT-u...
[ misk0 @ 15.11.2006. 21:56 ] @
Citat:

"The value of mysql_insert_id() is affected only by statements issued within the current client connection. It is not affected by statements issued by other clients."


Ovo je Dejan napisao u jednoj drugoj temi ali to je ono sto tebi rjesava problem. Znaci sa tom komandom imas defitivno ID od rekorda insertovanog u toj sesiji tj toj konekciji tako da te ne interesuje da li je u medjuvremenu u bazu unesen jos 1 ili 5 rekoda sa vecim IDom.

Bar tako ja kontam..