Autor Zpráva
Majkelju
Profil
Na webu zasílám skrze form potvrzovací linky s aktivačními kódy a chci jim nastavit platnost 48h. U každého vytvořeného záznamu v tabulce s těmito aktivačními kódy jsem tedy přidal sloupec typu TIMESTAMP s časem vytvoření a teď bych rád v phpmyadmin vytvořil event, který bude každou hodinu projíždět tu tabulku a záznamy starší, než 48h smaže.
A tady nastává můj problém - SQL dotaz mi vyhodí chybu, že nemám přístup. Dopátral jsem se, že je potřeba provést dotaz SET @@global.even­t_scheduler = ON. Jenže když se pokusím o toto, tak to nejede, prý jsou k tomu potřeba práva superuživatele. Bohužel už jsem se nedokázal dopídit, jak tato práva získám, co je potřeba kam napsat.
Mohl by mi prosím někdo poradit postup, jak na to? Případně jak docílit toho, co potřebuju nějak jinak? Napadlo mě, jestli se dá nějak nastavit životnost záznamu přímo při vytvoření, ale tuším, že v tom budu mít smůlu, zatím jsem nenašel, co potřebuju.
Enko
Profil
Můžeš si například udělat naplánovanou úlohu přes Cron a zpracovávat to z PHP nebo z jiného jazyka, nevím co ti tam jede.
Keeehi
Profil
Majkelju:
A vadí ti něčemu, že tam ty staré záznamy jsou?
Majkelju
Profil
Enko:
Díky, nemám nejmenší tušení, co to je Cron a jak to funguje, ale nastuduju.

Keeehi:
Vadí. Některé části funkcionality jsou totiž založeny na tom, zda sql dotaz v db najde nějaký záznam.
Pro přiblížení - jde o tabulku klienti_produkty, ve které se záznam vytvoří, když uživatel klikne na zakoupení produktu. V záznamu je krom id uživatele, id produktu a timestampu i náhodně vygenerovaný kód. Adminovi se odešle mail s potvrzovacím linkem, kterým uživateli po zaplacení potvrdí nákup, resp. aktivuje produkt. Aktivací produktu se náhodný kód v záznamu přepíše na NULL. V aplikaci tedy rozlišuji 3 stavy - Nezakoupeno (neexistuje záznam), zakoupeno (kód je náhodný string) a aktivováno (kód = NULL). No a jelikož zadání zní: po 48h aktivační link zneplatnit, potřebuju se záznamu úplně zbavit. Respektive všech záznamů o koupi, kde nebyl produkt během těch 48h aktivován.

Opravdu je vytvoření eventu taková složitost, že je k tomu potřeba ten Cron? PHP skriptem se to asi nevyřeší, že? Ten se spustí jen když uživatel vleze na stránky...
Keeehi
Profil
Takže uživatel si něco koupí a administrátor mu to musí do 48 hodin aktivovat. A když to nestihne, ta chceš, aby to už udělat nemohl. Takže přesto že uživatel zaplatil tak nic nemá, protože to administrátor nestihl. To je kolosální blbost už z hlediska business návrhu.
No a z hlediska návrhu databáze by to, jestli je nějaký produkt aktivovaný nebo ne nemělo záležet na hodnotě potvrzovacího tokenu.
Majkelju
Profil
Keeehi:
Přestaň si prosím domýšlet, jak v aplikaci fungují věci kolem a dělat závěry ;) Je to vymyšleno tak, že uživatel musí zaplatit v hotovosti na sídle firmy a člověk v kanclu, co bude mít přístup na ten mail. mu to tam rovnou odbouchne. Neptej se proč, prostě takový jsem dostal zadání :)) Pak bude moct případně žádost o koupi zaslat znovu, aniž by platil 2x, když nestihne zaplatit.
Jediný, co potřebuju vědět je, jak se dopracovat k tomu, co potřebuju udělat. Tzn. provádět eventy, pokud možno bez instalování věcí navíc. Stejně tam budu muset mít víc různých eventů pro další věci. Nejen mazání.
Tohle okecávání kolem je myslím si zbytečný.
Keeehi
Profil
Majkelju:
Tohle okecávání kolem je myslím si zbytečný.
Ani není. Máš prasácký návrh a pak jsi nucen hledat komplikovaná řešení. To že ty záznamy i po expiraci budou v databázi ničemu nevadí. Stačí si vždy zkontrolovat timestamp, zda je platný.
Otázka by pak mohla být: "Proč mám vždy kontrolovat i platnost timestampu?" Odpověď: protože patláš dohromady stav aplikace a nějaké technické zajištění ověření. Kdyby to bylo navržené normálně, něco takového by tě vůbec netrápilo. Ale dobrá, měl bych řešení které odpovídá stylu aplikace - najmi si Inda který se do databáze bude připojovat a záznamy mazat.
Enko
Profil
Souhlasím s tím, co napsal Keeehi Návrh logiky lze udělat mnohem efektivněji. Téměř vždy je potřeba zákazníkopvi navrhnout lepší logiku, protože si to zákazník prakticky nikdy nedokáže přesně domyslet, jak to bude vypadat ve skutečnosti a na řadu přijdou zbytečné tahanice, protože to chce zákazník předělat, atd...
Joker
Profil
Majkelju:
Jak naznačuje Keeehi: Když podezřele často narážíte na technická omezení databáze, je to obvykle známka, že jste špatně zvolil způsob řešení problému.

Napadlo mě, jestli se dá nějak nastavit životnost záznamu přímo při vytvoření
Vždyť ji tam máte.
Máte tam čas vytvoření záznamu. Platné záznamy jsou ty, které mají čas vytvoření později než (teď mínus doba vypršení).

Některé části funkcionality jsou totiž založeny na tom, zda sql dotaz v db najde nějaký záznam.
Ale když napíšete dotaz jen na platné záznamy, nevrátí nic i když tam budou neplatné záznamy.

Opravdu je vytvoření eventu taková složitost, že je k tomu potřeba ten Cron?
Spíš bych řekl, že uvedený problém tak řešit ani nejde, resp. jde jen silně neprakticky.

I když to časované mazání zprovozníte, nebude životnost záznamů 48 hodin, ale v podstatě náhodná doba v intervalu 48-49 hodin (prostě podle toho, kdy se spustí ten skript).
Budou existovat záznamy, které by už neměly být platné, ale stále platné jsou, protože se ještě nespustil ten mazací skript.

Navíc se ten mazací skript bude muset zbytečně spouštět i když nebude co mazat a zbytečně se do řetězu přidává další článek, který se může rozbít: Když mazací skript přestane fungovat, zůstanou všechny záznamy platné než si někdo všimne, že se to nepromazává.
Jelikož je docela pravděpodobné, že „člověk v kanclu, co bude mít přístup na ten mail. mu to tam rovnou odbouchne“ a nebude důsledně kontrolovat platnost záznamu (ostatně to automatické mazání tam předpokládám je právě proto, aby to nemusel dělat), může takový „rozbitý“ stav trvat hodně dlouho.

V aplikaci tedy rozlišuji 3 stavy - Nezakoupeno (neexistuje záznam), zakoupeno (kód je náhodný string) a aktivováno (kód = NULL)

Existuje čtvrtý, potenciálně dost zajímavý, stav, který tenhle návrh spojuje s prvním: Objednáno, ale neaktivováno v termínu.
Váš návrh např. neumožňuje zjistit, jak často si někdo vyžádal kód a pak ho nikdy neaktivoval.
A když někdo přijde s tím, že si objednal, zaplatil, ale kód se mu neaktivoval, nemáte to jak ověřit.

Jediný, co potřebuju vědět je, jak se dopracovat k tomu, co potřebuju udělat.

A to se tu taky řeší.
Když někdo stojí v bažině a zeptá se, kterým dalším směrem udělat krok aby byl blíž k městu, správná odpověď není ho poslat hlouběji do bažiny (byť by to i technicky bylo správně), ale říct mu, že došel do bažiny a jestli chce dojít do města, musí se vrátit a jít jinudy.
Kajman
Profil
Osobně bych si přidal sloupec s datem vypršení platnosti. Nový sloupec má výhodu, že můžete mít různé intervaly platnosti (např. v novém roce to budou tři dny, nebo pro jeden záznam chcete platnost zvýšit). Díky where jednoduše omezíte výpis na platné záznamy.
Majkelju
Profil
Joker:
Super, děkuju moc, konečně konstruktivní odpověď!
Nehádám se o tom, že můj návrh je bůhvíjak kvalitní...vím, že není, ale udělal jsem to nejlíp, jak momentálně dovedu, web tohoto typu dělám úplně poprvé (na mou obhajobu krom mojí nezkušenosti snad jen, že jde, ač to možná tak nevypadá, o stránky poměrně jednoduché včetně toho obchodního modelu-vše probíhá na bázi osobního kontaktu a hotovosti).
Jen jsem už nedoufal, že mi tu někdo dovede inteligentně odpovědět na jednoduchou otázku. Tzn. jiným stylem než "máš prasácký návrh, je to kolosální blbost a jak se dobrat řešení ti nepovím, radši si najmi Inda".
Příště půjdu pro radu radši na stackoverflow, tam si čtení takovýchhle pitomých kydů ušetřím :))

Každopádně za tuto odpověď ještě jednou děkuju, díky ní jsem si uvědomil pár věcí, co mě snad v psaní kódu posunou o kousek dál.


Kajman:
Aha, takže se přímo v tabulce dá nastavit sloupec s formátem datumu jako např TIMESTAMP, ale zároveň se mu bude odpočítávat platnost? Pod jakým klíčovým slovem bych o tom mohl něco vygooglit?
Prochy
Profil
Ne, nebude se ničemu odpočítávat planost. Je to obyčejný sloupec typu datetime, kde nastavíš, že planost toho záznamu vyprší např. 20. 4. 2017 11:44 a pak podle toho vytvoříš SQL dotaz, který bude vybírat pouze platné řádky tabulky.
Majkelju
Profil
Prochy:
Pořád ale nerozumím, jak tu platnost nastavím :( Hledal jsem to v phpmyadminu ve struktuře tabulky, tam mám jen možnost ON UPDATE...možnost nastavení expirace nemůžu najít.
Kajman
Profil
Tak ještě jednou... záznam tam bude stále. Čas platnosti tokenu je jen pro Vás, samotná databáze s ní neoperuje. Když ověřujete token, tak přidáte podmínku, že platnost nevypršela.

Něco jako
select * from `tabulka` where `token`='abc' and `platnost`>=now()
Majkelju
Profil
Kajman:
Ahá! :) nj zase hledám složitosti tam, kde nejsou. Díky za trpělivost!
Keeehi
Profil
Majkelju:
Jen jsem už nedoufal, že mi tu někdo dovede inteligentně odpovědět na jednoduchou otázku.
O to jsem se snažil už od začátku. Až do této doby jsi se však odmítal otočit a vyjít ven z té pomyslné bažiny. Já mám taky jen jednu trpělivost, takže kdo chce kam ...
Jsem rád, že už jsi si v tom udělal jasno.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: