Diskuze: Nasledujúce ID v databáze
V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 11 zpráv z 11.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Online test znalostí SQL a databází, jsme si ověřili nabyté zkušenosti z kurzu.
Pokud myslíš MySQL/MariaDB tak žádná oficiální možnost neexistuje, není k tomu ani moc důvod. Zjistit se ale dá poslední hodnota:
SELECT LAST_INSERT_ID()
Proč by to nemělo jít. Vždyť normálně např. phpmyadmin tuto hodnotu umí zobrazit. A jelikož používám mariadb tak vím že to jde.
Ahoj je to jednoduché složí k tomu tento dotaz
SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = ""
AND TABLE_NAME = ""
Výsledek pak můžeš vidět v příloze kterou přidávám
Kdyz nahravas obrazky k formulari, vlozis formular, pres lastinsert id
zjistis, jake ti priradil id a to pak pouzijes pro ukladani obrazku. Id dalsiho
zaznamu nepotrebujes, kdyz vis posledni, ne?
A jinak s tim docela bacha, pokud nepracujes v transakci a tvuj cyklus
generujici sql dotazy bude dostatecne pomaly, tak pri id+1 id+2 id+3 se muze
stat, ze mezitim jiny script v pameti dela totez a ti tam vlozi zaznam Cili, vzdycky jit pres
last_insert_id a idealne pres transakce, pokud navysujes id vic nez o +1.
Pokud jde o MySQL, tomuhle přístupu bych se vyhnul.
Proč?
Kdysi jsem ho použil. Fungovalo to krásně, dokonce snad ani nenastala žádná race-condition.
Problém nastal v momentě, kdy jsem přemigroval databázi na novou - verze 8.0
Obsah tabulky information_schema.TABLES jsou totiž jen statistický informace, které nemusí být aktuální.
Viz dokumentace dokumentace :
Columns in TABLES that represent table statistics hold cached values. The information_schema_stats_expiry system variable defines the period of time before cached table statistics expire. The default is 86400 seconds (24 hours). If there are no cached statistics or statistics have expired, statistics are retrieved from storage engines when querying table statistics columns.
Poučný je taky tenhle bug report bug report .
Ten člověk měl úplně stejný problém jako já
Obcházení pomocí nastavení hodnoty 0 do information_schema_stats_expiry bych taky nedporučoval: Bez toho nastavení ta aplikace nemusí fungovat správně. Takže si to musíš pamatovat, nebo zapsat někam do dokumentace. Pokud podobných specialit vznikne časem více, může z toho být pěkná noční můra.
Pokud ti jde o race condition pri použítí LAST_INSERT_ID, pak dokumentace dokumentace :
For LAST_INSERT_ID(), the most recently generated ID is maintained in the server on a per-connection basis. It is not changed by another client. It is not even changed if you update another AUTO_INCREMENT column with a nonmagic value (that is, a value that is not NULL and not 0). Using LAST_INSERT_ID() and AUTO_INCREMENT columns simultaneously from multiple clients is perfectly valid. Each client will receive the last inserted ID for the last statement that client executed.
Pro zajištění, že ti jiný klient neovlivní hodnotu vrácenou funkcí LAST_INSERT_ID() jsou transakce zbytečný (a ani si nejsem jistej, že něco takového zaručují - jsou přeci určeny k něčemu trochu jinému).
Jasne, ale nevim, zda si rozumime.
[b] lze vyresit transakcemi a nebo idealne neco takoveho vubec nedelat. Treba
bys mu poradil neco lepsiho, kdyby popsal problem konkretneji, na prikldu, proc
zrovna toto potrebuje
Transakce zajistí (doufejme), že se provede všechno, nebo nic. Nezajistí ale, že paralelně nepoběží druhá, ta stejná transakce, která vloží nová IDčka.
Nemám to podložený (možná někdo v dokumentaci to bude), ale myslím si, že transakce nezamkne tabulku pro zápis (možná u myisam tabulek, innodb jsou afaik zamykaný po řádcích).
Nepoléhal bych se tedy na to, že transakce tenhle problém vyřeší.
Problém je v tom, že IDčka by měla přiřazovat databáze, nikoliv hádat, co by tam mělo být ještě před samotným insertem.
Nemá ale moc smysl tohle řešit. Je to jak píšeš, pro nějaký smyslupný návrh to chce od OP detailnější popis.
Tak máš zřejmě pravdu. Teď jsem četl nějakou teorii a tranksace by snad, teoreticky i tenhle případ měla podchytit.
Co se člověk všechno nedoví :/
Zalezi na nastaveni sql. Vetsinou jsou sql prikazy zpusobem
prikaz; commit; prikaz; commit;...
Cili se prikaz ihned odesle do db. Kdyz ale otevres transakci, tak to vypada
takto
Start; prikaz; prikaz; prikaz; commit; end;
A navic, u transakce muzes nastavi, ze kdyz nektery z prikazu selze, tak celou
transakci do db neulozi a spusti nejake jine prikazy, treba ulozi error do
logu.
Zobrazeno 11 zpráv z 11.