ugrás a tartalomhoz

SessionID-k adatbázisba mentés során SQL hiba mysql_affected_rows() miatt

saxus · 2005. Júl. 8. (P), 22.23
Van egy ilyen Sessions tábla frissítő kódom (az SQL rétegben a függvények megfelelnek a mysql hasonló nevű függvényeivel, a $db class működik rendese, abban nincs hiba):

// SESSID konstans értelemszerűen a session id
$db->sql_query('UPDATE sessions SET ... last='.time().' WHERE id=\''.SESSID.'\' LIMIT 1');

if ($db->sql_affected_rows() == 0) {
$db->sql_query('INSERT INTO sessions (...) VALUES (...)');
}


Normális esetben semmi gond nincs ezzel az eljárással, csak akkor van gond, ha egy másodpercen bellül kétszer frissítem az oldalt (pl. véletlen duplaclick), ugyanis ekkor SQL hibát jelez. Kis kutakodás után a php manualban megtaláltam a hiba okát:

Ha UPDATE-tel használod, a MySQL nem fogja azokat a sorokat frissíteni, ahol a sor régi és új értéke megegyezik. Így nem kizárt, hogy a mysql_affected_rows() függvény nem pont az egyező sorok számát adja vissza, hanem csak a ténylegesen megváltoztatott sorok számát.


Kis keresgélés után ráakadtam a mysql_info() függvényre. Azzal ugyan le tudom kérdezni azt, hogy hány sor felel meg a feltételnek és hány módosult, csak nem tartom túl jó ötletnek egy stringből kibányászni számadatot.
 
1

timestamp

Sweetchack · 2005. Júl. 10. (V), 10.57
Ilyen problémával még nem találkoztam.
Tudsz arról, hogy a MySQL-ben a timestamp mező update-nél autómatikusan változik a pontos időre? Ha 2 timestamp van akkor csak az első.

Csinálhatod azt is, hogy lekérdezed a SESSID azonosítóval rendelkező rekordot, ha létezik akkor UPDATE ha nincsen akkor INSERT.
2

+1 SQL

saxus · 2005. Júl. 10. (V), 16.09
Itt a last mező szimpla INT típusú.

Korábban úgy volt, ahogy mondtad, hogy először SELECT azután UPDATE vagy INSERT, csak azután áttértem erre, mert ez egyel kevesebb SQL kérést használ (statisztikáknál pl jó, mert azt gyakran csak egyszer kell beírni).

És addig működik is, ameddig véletlen nem kattintok kétszer ugyanoda, vagy nyomok F5-t. Csak sajnos a tapasztalat azt mutatja, hogy az ilyen véletlen duplaletöltésekre is figyelni kell. Nekem fel sem tűnt volna, hogyha az oldal fórumába nem írják bele.

Nekem meg a mániám, hogy minél gyorsabb kódot írjak (szerencsére nem hajt annyira a tatár), és a SELECT+UPDATE módszerrel az a gond, hogy azok végignézik az egész táblát, tehát kétszer kell végigolvasni a sessions táblát. És általában az UPDATE-nak van nagyobb esélye, szóval időben a SELECT+INSERT kb ugyanannyi (kicsivel talán kevesebb, mivel nem kell írni a táblába), viszont a SELECT+UPDATE kb kétszerannyi. Tudom, LIMIT 1 és megáll a tábla végén, de ha teszem azt a tábla közepén van (és még sok session van), akkor kétszer kell ellavíroznia a dbms-nek a tábla közepéig.

Vagy ilyenen már nagyon elborultság gondolkozni? :P

Max úgy lehetne kiküszöbölni, hogy bevezetek egy számlálót, aminek 0 kezdőértéket adok, és mindig növelek egyel, ezáltal még kapok egy jó kis statot arról, hogy hányszor kérte le oldalt. Haszna mondjuk nincs (max extra bigyula), de a jelenség kiküszöbölhető lenne ezzel.

Az egészben az a szép, hogy - elvileg - a PostgreSQL-s pg_affected_rows() úgy működik, ahogy várnám. Legalábbis ott nem írják megjegyzés, hogy hasonlóan működik, mint a mysql-s társa.
3

Indexek

Sweetchack · 2005. Júl. 12. (K), 12.33
Pont erre találták ki az indexeket.
Ha van index a SESSID-t tároló mezőn akkor sokkal gyorsabban megy minden lekérdezés. (Az olyanok amiben a WHERE záradékban szerebel az indexelt mező).

Amúgy meg MySQL esetén érdekes olvasmány lehet:
http://dev.mysql.com/doc/mysql/en/replace.html
részlet:
REPLACE works exactly like INSERT, except that if an old record in the table has the same value as a new record for a PRIMARY KEY or a UNIQUE index, the old record is deleted before the new record is inserted.