Pereiti prie turinio

SQL unikalus įrašas


Rekomenduojami pranešimai

Sveiki,

Taigi idėja tokia:

Sukurti automatiškai vartotoja su unikaliu vardu t.y vardas neturėtu pasikartoti duomenų bazej.

vartotjo vardas butu su prefiksu `vartotojas` su 4 ženkliu skaučium.

pvz.: vartotojas0001 , vartotojas0004 , vartotojas0264.

Tik nelabai išgalvoju kaip čia padarius.

Gal bus patarimu?

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Tai čia gi simple ar aš kažko nesupratau?

 

$vardas = 'vardas';
$suffix = rand(1000,9999);
$new_vardas = $vardas.$suffix;

 

Čia susigeneruos random, dar galima auto increment'inti ir prie visko pries irasant patikrinti ar tokio nera jei yra dar karta prasukti (jei rand naudojama).

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Tai čia gi simple ar aš kažko nesupratau?

 

$vardas = 'vardas';
$suffix = rand(1000,9999);
$new_vardas = $vardas.$suffix;

 

Čia susigeneruos random, dar galima auto increment'inti ir prie visko pries irasant patikrinti ar tokio nera jei yra dar karta prasukti (jei rand naudojama).

bet yra šansas , kad toki pati skaičiu sugeneruos su rand :D

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Tai ir sakau prieš įrašant patikrinti ar nėra tokio, jei yra sukti dar karta, tau bet kokiu atveju 4 skaitmenų diapazonas baigsis per ne tokį ir didelė laiką. Na nebent nebus ten daug vartotojų, o jei tada nebus tai ir šansų jog susigeneruos tas pats mažai.

 

Apskritai būdu čia tą padaryti labai daug yra.

Redagavo itpagalba
Nuoroda į pranešimą
Dalintis kituose puslapiuose

juokauji...

 

$vardas = 'vardas_';
$suffix = rand(1000,9999);
$new_vardas = $vardas.$suffix;

 

geras variantas! o jeigu bijai dėl to, kad bus daug userių, tai generuoji ne iš skaičių, o iš raidžių ir skaičių masyvo ar kokių kombinacijų, dėl to tikrai bus šimtai tūkstančių skirtingų kombinacijų. O šiaip ir iš tų skaičių paprasčiausiai padarai ir suki ciklą tol, kol gražina TRUE (tokių įrašų nėra) ir tada gali įrašyti. Bet šiaip retas atvejis, kai tau suks ciklą daugiau nei 5 kartus, o kadangi čia toks ciklas net nejuntamas, tai ir 10 ir 15 kartų nesijaustų manau

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Bet šiaip retas atvejis, kai tau suks ciklą daugiau nei 5 kartus, o kadangi čia toks ciklas net nejuntamas, tai ir 10 ir 15 kartų nesijaustų manau

SQL užklausos cikle, kai to visai nereikia – biškį feispalmovičius. Kodėl netinka autoincrement (vienokia ar kitokia forma)?

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Jei nori daryti vartotoją su unikaliu vardu (vartotojas0001, vartotojas0004, vartotojas0264), tai tau būtinai reikės sukti ciklą prieš DB update'ą, kur tikrintų ar vardas nesikartoja.

Jei tau tokio vartotojo vardo reikia dėl primary key, tai patariu geriau pasidaryti lauką ID naudojant autoincrement.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

lolwut? Palieki viskas kaip yra - tegu ID būna paprastas INTeger'is, su autoincrement'u, o kai trauki duomenis iš duombazės tai tiesiog pridėk žodį "vartotojas" ir leading zeros (pvz. su sprintf()):

<?php
$name = sprintf('vartotojas%04d', $row['id']);
?>

arba jeigu labai jau norisi turėti fizišką column'ą su tokia reikšme (nesugalvoju realios situacijos, kam to galėtų reikėt), tada gali sukurti atskirą, ir parašyti MySQL trigerį, kad setintų tą column'ą su prefixu + ID:

DELIMITER $$

CREATE TRIGGER `VartotojasSubfix`
AFTER INSERT ON lentos_pavadinimas

FOR EACH ROW
BEGIN
   UPDATE lentos_pavadinimas
   SET `name` = CONCAT('vartotojas', NEW.`id` )
   WHERE `id` = NEW.`id`;
END $$

DELIMITER;

(čia aišku be leading zeros, bet esmė aiški)

Redagavo vitalikaz
Nuoroda į pranešimą
Dalintis kituose puslapiuose

dabar buvau pasidares taip:

$naujasvardas = 'USER'.current(mysql_fetch_array(mysql_query("SELECT MAX(id)+1 FROM `vartotojai`")));

Tiesiog gaminau chata, užėjusiam sveičiui buvo sukuriamas nikas.

Tai sugalvojau tiesiog uždėt draudima keist nika su prefiksu USER[skaičius].

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Nenaudok ext/mysql.

+ Manau, turėsi race condition (jei tik būsi bent tiek populiarus, kad du vartotojai vienu metu registruotųsi):

 

PHP procesai: A ir B
Vartotojai: 1 ir 2
Dabartinis ID: 314

1 ir 2 nori užsiregistruoti tuo pačiu metu.

A paima 1-am ID 315
B paima 2-am ID 315
A siunčia užklausą, bandydamas įrašyti USER315
B siunčia užklausą, bandydamas įrašyti USER315

KABOOM.

Redagavo Silke
Nuoroda į pranešimą
Dalintis kituose puslapiuose

dabar buvau pasidares taip:

$naujasvardas = 'USER'.current(mysql_fetch_array(mysql_query("SELECT MAX(id)+1 FROM `vartotojai`")));

Tiesiog gaminau chata, užėjusiam sveičiui buvo sukuriamas nikas.

Tai sugalvojau tiesiog uždėt draudima keist nika su prefiksu USER[skaičius].

Nesu garantuotas ar viskas bus gerai, bet siūlau bandyt tokį variantą

$IP = $_SERVER['REMOTE_ADDR'];
mysql_query("INSERT INTO `vartotojai`(ID, NAME, IP) VALUES(NULL,'','$IP')");
$naujasvardas = 'USER'.current(mysql_fetch_array(mysql_query("SELECT ID FROM `vartotojai` WHERE IP='$IP'")));
mysql_query("UPDATE `vartotojai` SET NAME=$naujasvardas WHERE IP='$IP'");

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Jeigu reikia šūstrai:

 

SELECT COUNT(*) AS `total` INTO @slug_number FROM user WHERE slug LIKE 'Min2liz%' OR slug LIKE 'Min2liz-[0-9]*';
SET @slug = CONCAT('Min2liz',IF(@slug_number = 0,'',CONCAT('-',@slug_number)));
INSERT INTO `user` (`user`,`slug`) VALUE('Min2liz',@slug)

 

 

jeigu paprastai:

 

1 Užklausa:

 

SELECT COUNT(*) AS `total` FROM user WHERE slug LIKE 'Min2liz%' OR slug LIKE 'Min2liz-[0-9]*';

 

2 Užklausa:

$slug = 'Min2liz-' . $row['total'];

INSERT INTO `user` (`user`,`slug`) VALUE('Min2liz',$slug)

 

P.S.

 

Lenta:

CREATE TABLE `user` (

`user` VARCHAR(50) NULL DEFAULT NULL,

`slug` VARCHAR(50) NULL DEFAULT NULL

)

Redagavo Min2liz
Nuoroda į pranešimą
Dalintis kituose puslapiuose

uniklaus irasas: $irasas=md5(uniqid(rand()));

LOL :lol: Labai įdomu net, kam tas sulūžęs MD5 ten...

 

Generating an MD5 from a unique ID is naive and reduces much of the value of unique IDs, as well as providing significant (attackable) stricture on the MD5 domain. That's a deeply broken thing to do. The correct approach is to use the unique ID on its own; it's already geared for non-collision.

 

O rand() – irgi ne pats geriausias PRNG.

Redagavo Silke
Nuoroda į pranešimą
Dalintis kituose puslapiuose

Nesu garantuotas ar viskas bus gerai, bet siūlau bandyt tokį variantą

$IP = $_SERVER['REMOTE_ADDR'];
mysql_query("INSERT INTO `vartotojai`(ID, NAME, IP) VALUES(NULL,'','$IP')");
$naujasvardas = 'USER'.current(mysql_fetch_array(mysql_query("SELECT ID FROM `vartotojai` WHERE IP='$IP'")));
mysql_query("UPDATE `vartotojai` SET NAME=$naujasvardas WHERE IP='$IP'");

kam tas update? ir prie insert tuscias name laukelis?

Nuoroda į pranešimą
Dalintis kituose puslapiuose

uniklaus irasas: $irasas=md5(uniqid(rand()));

stipru čia :D tai jeigu jau tokiais "unikalumais" dalinamės, tai kodėl nepabandžius ko nors su bcrypt? :D jeigu jau su md5 kažką darai tai pilnai pakanka md5(time()); ir gausi unikalų įrašą, o jei bijai, kad tą pačią sekundę reginsis keli useriai tai jau reik domėtis kaip pagaminti unikalų įrašą

Nuoroda į pranešimą
Dalintis kituose puslapiuose

stipru čia :D tai jeigu jau tokiais "unikalumais" dalinamės, tai kodėl nepabandžius ko nors su bcrypt? :D jeigu jau su md5 kažką darai tai pilnai pakanka md5(time()); ir gausi unikalų įrašą, o jei bijai, kad tą pačią sekundę reginsis keli useriai tai jau reik domėtis kaip pagaminti unikalų įrašą

Apskritai, kam čia to hash'o? Kaip jau rašiau kitam poste, uniqid() ir taip duoda pakankamai retai pasikartojančią reikšmę + ir taip hexu koduotą... md5 čia nieko neduoda, tik atima.

Nuoroda į pranešimą
Dalintis kituose puslapiuose

kam tas update? ir prie insert tuscias name laukelis?

 

Update, kad kitą kartą prisijungus vartotojui jis matytų savo nick (arba kitus duomenis), nes būtų galimybė paimti pagal IP.

O dėl tuščio lauko, tai galima ir taip tikriausiai (nelabai pamenu ar nemes klaidos):

mysql_query("INSERT INTO `vartotojai`(ID, IP) VALUES(NULL,'$IP')");

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Update, kad kitą kartą prisijungus vartotojui jis matytų savo nick (arba kitus duomenis), nes būtų galimybė paimti pagal IP.

O dėl tuščio lauko, tai galima ir taip tikriausiai (nelabai pamenu ar nemes klaidos):

mysql_query("INSERT INTO `vartotojai`(ID, IP) VALUES(NULL,'$IP')");

Į primary key vargu, ar įkiši NULL.

Ir...

mysql_query

mysql_query

mysql_query

mysql_query :(

Nuoroda į pranešimą
Dalintis kituose puslapiuose

Prisijunkite prie diskusijos

Jūs galite rašyti dabar, o registruotis vėliau. Jeigu turite paskyrą, prisijunkite dabar, kad rašytumėte iš savo paskyros.

Svečias
Parašykite atsakymą...

×   Įdėta kaip raiškusis tekstas.   Atkurti formatavimą

  Only 75 emoji are allowed.

×   Nuorodos turinys įdėtas automatiškai.   Rodyti kaip įprastą nuorodą

×   Jūsų anksčiau įrašytas turinys buvo atkurtas.   Išvalyti redaktorių

×   You cannot paste images directly. Upload or insert images from URL.

Įkraunama...
  • Dabar naršo   0 narių

    Nei vienas registruotas narys šiuo metu nežiūri šio puslapio.

  • Prisijunk prie bendruomenės dabar!

    Uždarbis.lt nariai domisi verslo, IT ir asmeninio tobulėjimo temomis, kartu sprendžia problemas, dalinasi žiniomis ir idėjomis, sutinka būsimus verslo partnerius ir dalyvauja gyvuose susitikimuose.

    Užsiregistruok dabar ir galėsi:

    ✔️ Dalyvauti diskusijose;

    ✔️ Kurti naujas temas;

    ✔️ Rašyti atsakymus;

    ✔️ Vertinti kitų žmonių pranešimus;

    ✔️ Susisiekti su bet kuriuo nariu asmeniškai;

    ✔️ Naudotis tamsia dizaino versija;

    ir dar daugiau.

    Registracija trunka ~30 sek. ir yra visiškai nemokama.

  • Naujausios temos

  • Karštos temos

×
×
  • Pasirinkite naujai kuriamo turinio tipą...