Sziasztok!
Küzdök egy problémával, felteszem itt is, hátha tudtok segíteni.
A feladat, hogy egy megrendeléshez az ügyfél könnyen megjegyezhető, de egyedi megrendelésazonosítót kapjon. Ehhez MySQL-t használnék, mert hogy az van. Viszont nem értek hozzá.
Amit elkövettem (és lokálisan, USB WEB Server-el működik is) az a következő SQL script:
CREATE TABLE IF NOT EXISTS `orders` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_hungarian_ci AUTO_INCREMENT=1 ;
DELIMITER $$
CREATE FUNCTION `get_next_id`() RETURNS int(11)
BEGIN
DECLARE ID INT(11);
delete from orders;
insert into orders (ID) values (0);
SELECT LAST_INSERT_ID() INTO ID;
RETURN (ID);
END$$
DELIMITER ;
A cél, hogy a get_next_id függvény visszaadjon az előzőnél eggyel nagyobb értéket.
Viszont a függvény scriptjének futtatásakor a következő hibaüzenetet kapom:
#1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
A neten talált "SET GLOBAL log_bin_trust_function_creators = 1;" megoldás nem jó, nincs hozzá meg a jogosultság.
Mit tehetek esetleg, hogy működjön, amit szeretnék?
Gábor
- 2406 megtekintés
Hozzászólások
- A hozzászóláshoz be kell jelentkezni
Sajna nem jó. Üzenet:
#1419 - You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)
- A hozzászóláshoz be kell jelentkezni
Egyikkel sem tudod létrehozni a függvényt?
By default, for a CREATE FUNCTION statement to be accepted, at least one of DETERMINISTIC, NO SQL, or READS SQL DATA must be specified explicitly.
https://dev.mysql.com/doc/refman/8.0/en/stored-programs-logging.html
- A hozzászóláshoz be kell jelentkezni
+1
Én is ezt mondanám. deterministic-el kellene mennie.
- A hozzászóláshoz be kell jelentkezni
Szerintem ennek így kellene mennie:
CREATE FUNCTION `get_next_id`() RETURNS int(11) DETERMINISTIC
BEGIN
DECLARE ID INT(11);
delete from orders;
insert into orders (ID) values (0);
SELECT LAST_INSERT_ID() INTO ID;
RETURN (ID);
END$$
DELIMITER ;
- A hozzászóláshoz be kell jelentkezni
Öööö... miért kell ehhez ez a függvény? Nem arról van esetleg szó, hogy van egy táblád valahol amiben rendelések vannak és abba kell valami egyedi azonosító?
Mert ha igen, akkor elvileg annyi elég lenne hogy felveszed azt az ID oszlopot abba a táblába úgy, ahogy a kódban is van:
`ID` int(11) NOT NULL AUTO_INCREMENT
Oszt ennyi.
- A hozzászóláshoz be kell jelentkezni
Szia!
Az adatbázisban semmit sem szeretnék tárolni. Egyetlen dologra kell: tudjak egyedi azonosítót prezentálni a webes felület számára. A megrendeléseket nem itt tartom nyilván, az más úton jut el hozzánk.
Azért kellett volna a függvény, hogy egy hívás alatt történjen meg a beszúrás és az ID lekérdezése, mert abban a pillanatban, hogy a php-ból két külön hívást kell indítanom - márpedig egyelőre nem látok más megoldást - problémát fognak okozni a párhuzamos folyamatok:
1. lépés: új rekord beszúrása a táblába
2. lépés: utolsó beszúrt ID lekérdezése
Ha párhuzamosan ketten adnak fel rendelést (mivel ez egy webes alkalmazás, nem kizárt!), akkor előfordulhat az az eset, hogy a 2. lépés előtt befigyelt egy másik folyamat 1. lépése, így mindketten ugyanazt az ID-t kapják vissza. Ezt a kockázatot szerettem volna minimálisra csökkenteni.
Gábor
- A hozzászóláshoz be kell jelentkezni
nem tudom, PHP-ból hogy működik a tranzakciókezelés, de annak meg kellene oldania ezt.
begin transaction;
insert into
select egyetlen sor
delete egyetlen sor
commit
Egyébként meg, ha csak az egyedi azonosító a cél, akkor UUID, GUID.
- A hozzászóláshoz be kell jelentkezni
https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html
sql parancsok php-ból:
lock tables orders write;
delete from orders;
insert into orders (ID) values (0);
select ID from orders;
unlock tables;
a 'select ID from orders' adja vissza az id-t amit keresel.
- A hozzászóláshoz be kell jelentkezni
Szerintem teljesen tévúton jársz.
Ha nem tárolod el, akkor meg miért is fontos? A felhasználó nem tud hivatkozni rá nálad, hiszen nincs meg neked, hogy az X azonosítójú számla melyik.
Egyedi sorszámot, vagy egyedi azonosítót? Azonosítóra használj UUID-et, PHP is tud generálni. Sőt, azonosíót képezhetsz is, dátumból, nevekből, mindenféle olyan adatból, amelyeknek az összessége egyedivé teszi az adott számot.
- A hozzászóláshoz be kell jelentkezni
+1
- A hozzászóláshoz be kell jelentkezni
Nem, nem járok tévúton. A teljes folyamat leírása hosszú és a konkrét problémától messzire vezet, ezért nem részleteztem.
Azért nem kell tárolni az így kapott azonosítót, mert a megrendelés - és annak generált azonosítója - más úton jut el a rendszerünkhöz (konkrétan e-mailben és ftp tárhelyre feltöltött, kötött formátumú txt állományban). Hogy miért így, teljesen mellékes, történelmi és praktikussági szempontok játszanak benne szerepet.
Eddig is generáltam megrendelés azonosítót php-ból így:
session_start();
$megrid = session_id()."_".$_SERVER['REQUEST_TIME'];
Ez mindaddig jó is, amíg az ügyfél csupán simplepayes kártyafizetéssel akar fizetni, mert ott nem számít a megrendelés azonosító hossza és kinézete (azt a rendszerek a háttérben adogatják át egymásnak), valamint garantáltan egyedi lesz. Viszont be szeretnénk vezetni az előreutalásos fizetési módot, ott nem mondhatom a vevőnek, hogy az utalás közleményrovatába írja be a következő szöveget: eom2ejnfdpuskir47irdnt8pk2_1535061590.
Ezért találtam ki, hogy kapjon egy bamba sorszámot, meg egy előtagot, amit az ügyfél sokkal egyszerűbben megjegyez (pl: X01547). Viszont ennek egyedinek kell lennie. Legegyszerűbb módszer erre, hogy adatbázis autoincrement mezője adja ezt az értéket, az adatbázis csupán erre kell.
- A hozzászóláshoz be kell jelentkezni
Miért fontos NEKED, hogy az ügyfél mit jegyez meg egyszerűen? Miért fontos az ügyfélnek? Valaminek a megjegyezhetősége (pláne azonosítóé) azért fontos, hogy utána visszakereshető legyen.
De ha nem tárolod te le, akkor nem lesz nálad visszakereshető ez alapján az eldobós azonosító alapján a megrendelés. Ha meg az ügyfél magának akarja visszakereshetővé tenni, akkor majd úgyis iktatja, és ad saját maga azonosítót neki. És azt meg ő jobban fogja tudni, hogy neki mi a jó azonosító, mint te.
A leírásod alapján az utalásazonosító NEKED mégis fontos, akkor meg miért nem tárolod el?
- A hozzászóláshoz be kell jelentkezni
ha jól értem, letárolják, csak nem DB-be.
- A hozzászóláshoz be kell jelentkezni
Akkor meg miért DB-vel kéne előállítani a sorszámot? :) Nem csak DB-vel lehet szigorú sorszámozást végeztetni.
- A hozzászóláshoz be kell jelentkezni
Azért fontos nekem, hogy az ügyfél mit jegyez meg jól, mert ha az ügyfél előreutalással fizeti ki a megrendelését, azt nekünk be is kell tudnunk azonosítani. Ügyfélkörünk az idősebb korosztály, tőlük nem tudjuk elvárni az olyan technikai tudást, hogy Ctrl-C + Ctrl-V párossal másolja át az utalás közleményébe az azonosítót.
Olyan emberekről van szó, akiknek még bankkártyájuk sincs, vagy nem bíznak a netes kártyás fizetésben!
Mint írtam, letárolom az azonosítót, de nem az adatbázisban.
- A hozzászóláshoz be kell jelentkezni
"Ha párhuzamosan ketten adnak fel rendelést (mivel ez egy webes alkalmazás, nem kizárt!), akkor előfordulhat az az eset, hogy a 2. lépés előtt befigyelt egy másik folyamat 1. lépése, így mindketten ugyanazt az ID-t kapják vissza. "
A LAST_INSERT_ID() az adott kapcsolat alapján adja vissza az utsó id-t. Egy másik kapcsolat insertje nem fog bezavarni.
- A hozzászóláshoz be kell jelentkezni
Ki kell ábrándítsalak, nincs igazad! Az autoincrement mezők (illetve generátorok) minden adatbázismotorban tranzakción kívül álló műveletek, ezért a LAST_INSERT_ID() mindig a ténylegesen utoljára beszúrt rekord azonosítóját adja vissza, akkor is, ha azt egy másik tranzakció kezdeményezte. És ezt nem csak a tanult ismereteimre alapozva állítom, hanem teszteltem a módszert és bizony elő tudtuk állítani az általam leírt szituációt, tehát két külön megrendelés kapta volna ugyanazt az azonosítót.
- A hozzászóláshoz be kell jelentkezni
még mindig megoldás, ha nem a
last_insert_id()
-t selecteled, hanem (az adott tranzakcióban) a táblában lévő egyetlen sort, nem?
- A hozzászóláshoz be kell jelentkezni
Én nem írtam tranzakcióról.
LAST_INSERT_ID() ...
"The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions."
https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#func…
- A hozzászóláshoz be kell jelentkezni
Ha saját bevallásod alapján sem értesz a mysql-hez, akkor miért akarod megszakérteni?
"The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client"
Vagyis ha php oldalról, te beszúrsz egy új sort a táblába, majd megnézed last_insert_id() -t, akkor az neked bizony unique lesz és nem fogja befolyásolni egy más szálon történt esemény
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
MySQL-hez konkrétan nem értek, de más adatbáziskezelőkhöz igen (ha firebird, IB, MSSQL, Oracle lenne a szerveren, nem is lett volna kérdésem). Elég sok szakkönyvet is olvastam, általános elvként elég sokszor elhangzott, amit írtam.
De ha ezeknek nem is hinnék, a lefuttatott tesztek eredményei igazolták a problémát: Ugyan csak ketten generáltattunk azonosítókat párhuzamosan, de bizony előfordult, hogy ugyanazt az ID-t kaptuk vissza!
- A hozzászóláshoz be kell jelentkezni
Akkor hibas volt a teszted. Nagyon sokan bajban lennenek a vilagban ha valoban ugy mukodne a dolog ahogy irod (a dokumentacio sem teged tamaszt ala)
Fogjuk meg a masik vegerol, mutasd a teszted
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
Csak nehogy aztán Te is ki legyél ábrándítva ;-D
- A hozzászóláshoz be kell jelentkezni
Nem igazan felek ettol az eshetosegtol ;)
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
A környezet: MySQL, benne orders tábla egyetlen ID autioncrement mezővel.
A PHP kód három dolgot csinál:
1. először beszúr egy sort a táblába, hogy generálódkon a következő érték: INSERT INTO orders VALUES ();
2. Lekérdezi az utoljára beszúrt értéket: SELECT LAST_INSERT_ID();
3. A visszakapott értéket megjeleníti az oldalon.
A teszt úgy zajlott, hogy a teszt weblap egy szövegre kattintgatva jquery + ajax segítségével kért egy azonosítót és azt belerakta egy listába.
Ezt az oldalt ketten a kollégámmal betöltöttük és elkezdtük vadul kattintgatni a szöveget. Átlag 5-6 értéket tudtunk kérni másodpercenként. Ezek után összehasonlítottuk a két listát és volt benne egyezés!
Ha a pontos kódra is kíváncsi vagy, kedden tudom mutatni, akkor leszek legközelebb.
- A hozzászóláshoz be kell jelentkezni
Hihetetlennek hangzik, hacsak nem így sikerült: http://php.net/manual/en/mysqlnd-mux.sharing_connections.php, vagy valami más trükk van...
- A hozzászóláshoz be kell jelentkezni
.
- A hozzászóláshoz be kell jelentkezni
Kerjuk a kodot, mert az lesz a hibas. A mysql Nem igy mukodik
// Happy debugging, suckers
#define true (rand() > 10)
- A hozzászóláshoz be kell jelentkezni
A PHP kód:
<?php
function Get_Next_ID()
{
$prefix = "X";
$servername = "localhost";
$username = "dbuser";
$password = "dbjelszo";
$dbname = "adatbazisnev";
$ret = "";
// Create connection
$conn = mysqli_connect($servername, $username, $password, $dbname);
// Check connection
if ($conn)
{
$sql = "INSERT INTO orders () VALUES ()";
$stmt = mysqli_prepare($conn, $sql);
mysqli_execute($stmt);
$sql = "SELECT LAST_INSERT_ID() as ID";
$result = mysqli_query($conn, $sql);
if (mysqli_num_rows($result) > 0)
{
$row = mysqli_fetch_assoc($result);
$ret = $row["ID"];
}
mysqli_close($conn);
}
$ret = "000000".$ret;
$ret = substr($ret, strlen($ret)-5, 5);
return $prefix.$ret;
}
?>
- A hozzászóláshoz be kell jelentkezni
http://php.net/manual/en/features.persistent-connections.php
Valószínű, hogy igazából NEM nyitottál új kapcsolatot MySQL felé.
A LAST_INSERT_ID pedig kapcsolatonként értelmezendő.
Simán előfordulhat az alábbi:
1. $conn = mysqli_connect($servername, $username, $password, $dbname); nem nyit kapcsolatot, hanem újrahasznál egy connection poolban lévőt.
2. Ezután mindkét script futás az (ugyanazon a MySQL kapcsolaton keresztül) végrehajtja az INSERT-et
3. Ezután mindkét script futás a másodikként lefutott insert LAST_INSERT_ID-jét adja vissza.
Teljesen ésszerű dolog. De hát többszálú programozáshoz érteni kell.
- A hozzászóláshoz be kell jelentkezni
Egy weboldalról beszélünk, ami tudva levőleg párhuzamosan használnak. Gondolom, itt a webserver connection pool-t használ, ebből adódhat ez a probléma. De mivel a szervert nem mi üzemeltetjük, a probléma pedig fent áll, így ez nekünk nem jó.
- A hozzászóláshoz be kell jelentkezni
Tehát, ha jól értem:
1. Nincs kontrollotok alatt a MySQL szerver (https://hup.hu/node/160523#comment-2259584), pedig ez kellene ahhoz, hogy olyan függvényt tudják írni, ami neked kell.
2. Nincs kontrollotok alatt a PHP beállítása a connection poolingra (https://hup.hu/node/160523#comment-2260699), pedig ez kell ahhoz, hogy a LAST_INSERT_ID() értéke azt adja, amit szeretnél.
Persze, amit még meg tudsz tenni, az az, hogy tranzakciókat használs, és a LAST_INSERT_ID lekérdezését és az INSERT-et egy darab tranzakcióban hajtod végre.
Ez meg fogja oldani a problémádat. De ahhoz, hogy ez jó legyen, ahhoz az kell, hogy a transaction isolation level jól be legyen állítva, hogy legalább READ COMMITED legyen.
Ezt ugye te csak MySQL sessionönként tudod megtenni, mert ahhoz, hogy GLOBAL szinten is a tranzakcióizoláció jó legyen, SUPER jogosultság kell, az meg nincs neked.
Ekkor viszont minden session-ben meg kell mondanod az elején, hogy SET SESSION TRANSACTION ISOLATION LEVEL = 'READ COMMITED'.
Erre figyelned kell.
Persze tranzakciók csak InnoDB táblák esetén használhatóak, MyISAM táblák esetén nincs értelmük.
Szóval jópár apróságnak kell jól beállítva és jól használva lennie, hogy a problémád helyesen megoldódjon.
És ez után még mindig MySQL műveletekkel akarod megoldani a problémádat. Én ezt gondnak látom.
- A hozzászóláshoz be kell jelentkezni
Én még nem láttam fehér embert, aki persistent kapcsolatot használt volna. Pláne olyat nem, aki ezt úgy tette, h igazából nem is tud róla. Sztem itt sincs erről szó.
2. Na ez az ami sztem nem képzelhető el. (nem azt jelenti h a processek kedvükre választanak maguknak a [z akár] használatban lévő kapcsolatok közül. Mindig csak a poolban lévő szabad kapcsolatot kaphatja meg - ha nincs szabad várnia kell -, ilyen formán kizárt, h két process egyidőben használjon azonos kapcsolatot)
A topiknyitó által leírt jelenség teljesen abszurd.
- A hozzászóláshoz be kell jelentkezni
Nem lehet, hogy mysqli_execute hibára fut néha?
- A hozzászóláshoz be kell jelentkezni
Ehhez nem kell sql, ha nem fontos, hogy növekvő legyen, de az fontos, hogy egyedi.
time().microtime().rand()
- A hozzászóláshoz be kell jelentkezni
MODIFIES SQL DATA a BEGIN elé (plusz NOT DETERMINISTIC még a MODIFIES SQL DATA elé)?
Bár az nem garantált, hogy egyel nagyobbat fogsz mindig kapni. Ehhez lock kellene, ahogy fentebb is írták.
- A hozzászóláshoz be kell jelentkezni
Nem megy, mert ahhoz SUPER jogosultság kellene, de az nincs.
- A hozzászóláshoz be kell jelentkezni
Pillanatnyilag megoldottam a problémát, bár nem teljesen olyan módon, ahogy azt eredetileg elképzeltem.
A módszer a következő:
- Készítettem egy egy táblát két mezővel:
- ID: autoincrement mező
- SessioID: varchar mező
- A php első lépésben generál egy egyedi azonosítót úgy, mint eddig:
- session_start();
- $megrid = session_id()."_".$_SERVER['REQUEST_TIME'];
- Az így generált - ténylegesen egyedi, de nehezen olvasható - azonosítót beszúrom az adatbázisba
- Lekérdezem a generált azonosítóhoz tartozó ID értékét
Ezzel megoldódott a problémám.
Gábor
- A hozzászóláshoz be kell jelentkezni
Sem a PHP-t, sem a MySQL-t nem ismerem, viszont rogton felmerult bennem a kerdes, hogy miert fuggvenyt probalsz deklaralni, miert nem stored procedure-t?
Ha jol ertelmezem, kivulrol hivod, raadasul az adatbazis allapotat modositod (tablaba inzertalsz/torolsz), a fuggveny nem erre valo.
- A hozzászóláshoz be kell jelentkezni
Egy darab ID-ért feltenni egy MySQL-t eléggé ágyúval a verébre. Ettől van egyszerűbb, pont annyira favágó módszer: egy mappában létrehozol egy $megrid nevű fájlt, sorba rendezed a mappában a fájlokat előbb létrehozási dátum majd név szerint, és a mappán belüli sorszám lesz az azonosító. Vagy még ettől is jobb: egy text fájlban tárolod az utolsó kiadott sorszámod, és file locking segítségével garantálod, hogy egyszerre ne tudja két folyamat írni/olvasni.
- A hozzászóláshoz be kell jelentkezni
Topicnyito, masodik sor: "Ehhez MySQL-t használnék, mert hogy az van."
A file kezelest egy webes backendnel en sokkal nagyobb ganyolasnak erzem, mint az adatbazissal torteno kommunikaciot (gondoljunk peldaul a skalazodasra - de pont egy G mernoknek magyarazzam ezt? :))
- A hozzászóláshoz be kell jelentkezni
Tele van a net online guid generatorral es az api-jukkal. Ha mar mindenkeppen global es unique id-t kell generalni.
Amit csinal az...khmmm...hat nagyon jo :D
- A hozzászóláshoz be kell jelentkezni
Mutass nekem egy embert (főleg idősebbet...), aki hiba nélkül megjegyez egy GUID értéket!
- A hozzászóláshoz be kell jelentkezni
Nem tudom, de jo parszor ha vasaroltam a netrol, es ilyen egyedi kodot kaptam, akkor azt ugye megkaptam emailben (vagy meg az oldalon letoltheto pdf-ben) hogy amikor majd utolag utalom a penzt legyek kedves ezt az azonositot beirni a kozlemeny mezobe.
Na most nalad egy sima algoritmus is eloallithatna ezt ahol a "vasarlod" valamilyen id-jet, a "termek" valamilyen id-jet es egy timestampet/fate-t hasznalsz es mondjuk nem lesz hosszabb a generalt string 10-12 karakternel.
https://api.random.org/json-rpc/1/basic - aztan generalsz 10 jegyu random azonositokat per tranzakcio
- A hozzászóláshoz be kell jelentkezni
Már írtam. Alapvetően idősebb korosztályról van szó, akiknek még az is kihívás, hogy a 6 jegyű ügyfélazoosítójúkat megjegyezzék, ami minden számlán, emailben szerepel. Ennél hosszabb azonosítót nem generálhatok nekik. Ők annyira antitalentumok az informatikában (és ezt nem bántásnak szánom, nem is várom el tőlük), hogy a Ctrl-V + Ctrl-C nekik már űrtechnika.
- A hozzászóláshoz be kell jelentkezni
Lehet, hogy igy van, de szerintem egy egyzeru mondatot "Kerem a vastagon szedett azonositot irja be a banki atutalas kozlemeny rovataba" eleg nekik, hogy amikor elkuldik a penzt elovegyek a papirt, pdf-et, akarmit es onnan bepotyogjek. Ezt meg a nagyanyam is tudja (86 eves) aki nem okostelefont hasznal, de ir es olvas betuket amit papiron kap, vagy anyam mutatja meg neki egy laptop kepernyojen.
- A hozzászóláshoz be kell jelentkezni
:) Van tapasztalatod ügyfelekkel? Nekem van... Szerinted mit lehet elvárni az olyan ügyfelektől például, akik megrendelik az árut, megkapják postán, vele együtt a számlát rajta a sárga csekkel. Nem fizeti ki, kap utána 3 felszólítást, mindegyiken egy-egy csekkel, aztán az utolsó felszólításnál elbattyog a postára és befizeti mind a 4 csekket...
Szóval nem véletlenül vannak az elvárásaim, nem fogtok tudni meggyőzni az ellenkezőjéről.
- A hozzászóláshoz be kell jelentkezni
"Szerinted mit lehet elvárni az olyan ügyfelektől például, akik megrendelik az árut, megkapják postán, vele együtt a számlát rajta a sárga csekkel. "
Erre való a futár és a futárnál való fizetés. Nem véletlenül csinálják ezt, a csekkes szarakodás helyett. Amennyit elköltesz ügyfélsupportra, annyiból majdnem ingyen is adhatod a futárszolgálatot.
- A hozzászóláshoz be kell jelentkezni
a fenti peldad alapjan pont nem szukseges semmifele inofrmatikai megoldason gondolkodnod. Az ellenkezojerol nem gyozol meg. :D
- A hozzászóláshoz be kell jelentkezni
Egyedi azonosító képzésre adatbázisban lévő függvényt hatalmas gányolásnak érzem.
- A hozzászóláshoz be kell jelentkezni
Sokadszor is elmondom: nem az egyediséggel van a bajom, hanem az egyediséggel ÉS A JÓL MEGJEGYEZHETŐSÉGGEL!
Ha csak unique kellene, azt már rég megoldottam.
De ha a DB-t erre gánynak érzed, kérlek, írj egy szebb megoldást. Könnyű a másik ötletét, megoldását leszólni, hogy közben nem írsz semmit.
- A hozzászóláshoz be kell jelentkezni
Írtam fentebb.
- A hozzászóláshoz be kell jelentkezni
Hát bocs, de webszerveren file műveletekkel operálni szerintem sokkal gázabb, mint egy már létező MySQL szervert használni ID generálásra... De ízlések és pofonok.
- A hozzászóláshoz be kell jelentkezni
Én abból indultam ki, hogy bárhogy csinálod, gáz lesz, és akkor ez kevésbé gáz :D.
- A hozzászóláshoz be kell jelentkezni
Például nagyon jó tud lenni egy egyszerű ügyfélazonosító és a dátum, ha éppen egy ügyfél egy napon csak egy megrendelést ad le (hiszen tipikusan idős emberek, bankkártya nélkül).
Ekkor bizyon az ügyfélszám-dátum, például 1234-20180824 egy tökéletesen jól képezhető azonosító, ami nagyon könnyen meg is jegyezhető, még logika is van benne, és ha elfelejtené az idős bácsika, akkor is újra tudja képezni saját maga is. És még adatbázis se kell hozzá.
- A hozzászóláshoz be kell jelentkezni
Az új ügyfél meg generálja magának az azonosítóját....
- A hozzászóláshoz be kell jelentkezni
Ki mondta, hogy az ügyfél magának generál azonosítót? Regisztrációkor nem kap? Lehet az azonosítója e-mail cím is, bármi, amit ő ad meg, amiről te őt be tudod azonosítani. Nem kell, hogy autoinkrementált adat legyen.
Azonosíthatod az ügyfelet akár a számlaszámáról is, és akkor még ügyfélazonosító sem kell, csak egy dátum, meg az, hogy honnan jött az befizetés.
A problémádat sokféle képpen meg lehet oldani, és az, hogy az ügyfeleidnek mi lesz kényelmes, meg könnyen megjegyezhető, azt az ügyfelek fogják tudni, és nem a MySQL.
Nyilván, ha neked csak kalapácsod van (MySQL), akkor mindent szögnek (MySQL autoincrement mezőnek) akarsz látni.
UX szempontból amúgy a kitalálható ID-k nem a legjobbak: valaki félregépeli egy számjeggyel a sorszámot, ami egy valid sorszám lesz, és máris másvalakinek a megrendelését fizette ki.
Egy véletlenszerű, vagy éppen a megrendelőazonosítót (ami nem feltétlenül sorszám ám) is tartalmazó megrendelésazonosító védettebb a vétlen elgépelések ellen, ami tipikusan fontos idős embereknél.
- A hozzászóláshoz be kell jelentkezni
"Ezzel megoldódott a problémám."
Igen, ezt hivjak agilis szoftverfejlesztesnek. Az utanad jovo meg majd csak fogja a fejet, hogy mi ez...
- A hozzászóláshoz be kell jelentkezni
És nem mer hozzányúlni, mert ha nem érti, akkor biztosan valami rettenetesen fontos és bonyolult dolog lesz :-)
Pláne, hogy csak erre használ adatbázist a szoftver :-).
- A hozzászóláshoz be kell jelentkezni
Az alapproblémát egyébként úgy lehetne még jobban megoldani, ha feltöltenél egy szótárat, és számok helyett szavak lennének a kulcsok. (leválogatva a rövidek, amik beférnek a közlemény mező egy sorába)
Amit már kifizettek, azt meg lehet jelölni, és egy idő után újrahasznosítani. Így nem fogynak el soha.
Egy értelmes szót sokkal könnyebb átmásolni, mint egy random számot.
- A hozzászóláshoz be kell jelentkezni
A különféle futárszolgálatok is sok esetben előre definiált tracking numberekkel dolgoznak, amiket újrahasznosítanak. Ez azért jó nekik, mert így az árut feladó emberkének van allokálva X db tracking number, és amikor felad egy terméket, megadja hozzá a tracking numbert, amit a futárszolgálat használ, és kiadhatja a vevőnek is.
- A hozzászóláshoz be kell jelentkezni