IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
M6692
Člen
Avatar
M6692:31.7.2020 21:09

Ahojte
Mám databázu v ktorej mám stĺpec ID nastavený ako primary key s autoincrement 1. Prosím Vás je možné zistiť ID ktoré bude priradené novému záznamu v databáze? V prípade že súvislo pridávam nové záznamy ( riadky ) je to jednoduché samozrejme to bude posledné ID + 1. No v prípade že pridám nový riadok, v zápätí ho vymažem už pri ďaľšom pridanom riadku mi bude ID vygenerované ako posledné ID + 2.

Zkusil jsem: Hľadal so na nete no nič som nevedel nájsť.

Chci docílit: Ďakujem

 
Odpovědět
31.7.2020 21:09
Avatar
Odpovídá na M6692
Neaktivní uživatel:31.7.2020 23:11

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()
Nahoru Odpovědět
31.7.2020 23:11
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Martin Suchodol:1.8.2020 6:30

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.

 
Nahoru Odpovědět
1.8.2020 6:30
Avatar
Odpovídá na M6692
Martin Suchodol:1.8.2020 6:35

Ahoj je to jednoduché složí k tomu tento dotaz

SELECT AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = ""
AND TABLE_NAME = ""
  • WHERE TABLE_SCHEMA -> jméno databáze
  • AND TABLE_NAME -> jméno tabulky

Výsledek pak můžeš vidět v příloze kterou přidávám

 
Nahoru Odpovědět
1.8.2020 6:35
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:21.8.2020 18:32

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.

 
Nahoru Odpovědět
21.8.2020 18:32
Avatar
Bugmaster
Člen
Avatar
Odpovídá na Martin Suchodol
Bugmaster:22.8.2020 23:25

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_sche­ma.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_sche­ma_stats_expi­ry 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_sche­ma_stats_expi­ry 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.

 
Nahoru Odpovědět
22.8.2020 23:25
Avatar
Bugmaster
Člen
Avatar
Odpovídá na Peter Mlich
Bugmaster:22.8.2020 23:52

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).

 
Nahoru Odpovědět
22.8.2020 23:52
Avatar
Peter Mlich
Člen
Avatar
Odpovídá na Bugmaster
Peter Mlich:24.8.2020 8:03

Jasne, ale nevim, zda si rozumime.

  1. INSERT -> LAST_INSERT_ID - to vetsinou je ok, cas mezi insertem a byva maly
  2. INSERT -> LAST_INSERT_ID -> INSERT id+1, INSERT id+2, INSERT id+3 - ukladas seriri dalsich insertu a davas jim id+1 id+2. Pokud ten cyklus budes mit dostatecne pomaly a v pameti jiny uzivatel spusti nad stejnou tabulkou take INSERT, muze se stat, ze treba tve id+2 se prekryje s druhym uzivatelem, jeho INSERT/LAST_IN­SERT_ID a vysledkem je, ze bud jeho zaznam prepises nebo ti program zkolabuje na erroru, ze takove id uz v db existuje. Jakoze, kdyz je 200 uzivatelu online, tak bezi 200 php kodu v nahodilem poradi, jak rychle a nahodile uzivatele klikaji. A kdyz se sejdou 2 takove programy... Db umi prijmout vice INSERTU od ruznych uzivatelu. Ale v transakci se vsechno od jednoho uzivatele provede jako jeden celek

[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 :)

Editováno 24.8.2020 8:06
 
Nahoru Odpovědět
24.8.2020 8:03
Avatar
Bugmaster
Člen
Avatar
Odpovídá na Peter Mlich
Bugmaster:24.8.2020 9:56

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.

 
Nahoru Odpovědět
24.8.2020 9:56
Avatar
Bugmaster
Člen
Avatar
Odpovídá na Peter Mlich
Bugmaster:24.8.2020 10:21

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í :/

 
Nahoru Odpovědět
24.8.2020 10:21
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:24.8.2020 10:40

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.

 
Nahoru Odpovědět
24.8.2020 10:40
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.