Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] Losowe numery i sprawdzanie z bazą danych
Forum PHP.pl > Forum > PHP
looimaster
Obecnie mój skrypt wygląda tak:

  1. <?php
  2. $num_grn = rand(1,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9);
  3. print("loop:: $num_grn<br>");
  4. while(mysql_num_rows(mysql_query("select id from users where user_account={$num_grn}"))){
  5. $num_grn = rand(1,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9);
  6. print("looped $num_grn<br>");
  7. }
  8. ?>


Czyli innymi słowy generuje jakiś numer, a jeśli taki numer znajduje się już w bazie to generuje go jeszcze raz. Przy połowie wykorzystanych (istniejących) numerów generowanie nowego będzie już utrudnione, a przy prawie zapełnionej bazie praktycznie niemożliwe (nie wspominając już o tym jak zostanie kilka numerów do zapełnienia bazy), ponieważ ciągle będzie trafiał na istniejące.
Co powinienem tu zmienić aby nowy numer generował się szybko nawet przy dużej ich ilości i był niepowtarzalny?
Cezar708
po pierwsze dlaczego nie ułatwisz sobie i nie zrobisz tak:

  1. <?php
  2. do {
  3. $num_grn = rand(10000000, 99999999);
  4. print("loop:: $num_grn<br>");
  5. }
  6. while(mysql_num_rows(mysql_query("select id from users where user_account={$num_grn}"));
  7. ?>


po drugie, masz kilka możliwości:
1. możesz zwiększyć liczbę cyfr w generowane liczbie, co baaardzo zmniejszy prawdopodobieństwo trafienia na tę samą
2. zamiast generowanej liczby użyj md5(microtime(true)), czyli wygeneruje Ci hash 32 znakowy, który praktycznie w Twoim przypadku będzie niepowtarzalny.

Pozdrawiam
looimaster
Cyfr musi być tyle lub jedną mniej, to ma służyć jako losowe loginy do kont więc 32 znaki odpadają.

7 lub 8 losowych cyfr, aż do zapełnienia bazy - o to mi chodzi.
phpion
Cytat(looimaster @ 22.05.2008, 13:55:25 ) *
Cyfr musi być tyle lub jedną mniej, to ma służyć jako losowe loginy do kont więc 32 znaki odpadają.

Dlaczego nie zastosujesz po prostu AUTO_INCREMENT? Coprawda wartości nie będą wtedy losowe tylko rosnące (od 1 do N) ale to chyba akurat najmniejszy problem winksmiley.jpg
Demio
Nie lepiej najpierw zrzucić wszystkie numery z bazy do tablicy, a potem z niej sprawdzać dostępność, zamiast wysyłać wiele zapytań na raz. Zapytania w pętli = die(); ;p

Ja najpierw wykonałbym tablicę z liczbami do losowania, potem usunął z niej elementy powtarzające się z tablicą numerów z bazy i wykorzystał array_rand dla tablicy do losowania aby uzyskać unikalną liczbę.
.radex
ew. możesz hasz skrócić z 32znaków do 8 za pomocą np. substr.

substr('tutaj_hasz', 0, 8);
looimaster
Demio, Twoje rozwiązanie wydaje mi się najbliższe tego czego szukam więc bardzo dziękuję, aczkolwiek czy jednorazowe robienie takiej tablicy składającej się z 90 milionów elementów nie potrwa... kilka dni? Nie wspominając już o przeszukiwaniu, modyfikacji i losowaniu.

@phpion
Stosuję auto_inc ale tylko do wypełniania klucza głównego, numery kont muszą mieć przynajmniej 7 cyfr... oczywiście można by zacząć od 999999 i kolejno wybierać numery ale miały być losowe, a nie kolejne.
.radex
no więc dlaczego nie możesz użyć uniqid(), albo md5(microtime()) ?

Trza sobie ułatwiać życie winksmiley.jpg
dr_bonzo
md5() nie daje ci gwarancji unikalnosci wartosci!!! Ani uniq ID.

Mozesz wrzucic wszystkie liczby od 10000000 do9999999 do bazy losowac jedna z nich, dodac login o tym ID i usunac wybrana wartosc. Taka tabele tworzysz raz! A baza sobie szybko po niej poszuka.
.radex
No pewnie, ale rand()'y też nie.
dr_bonzo
rand() same w sobie nie, ale on sprawdzal czy aby mu sie nie powtarzaja
.radex
No pewnie, ale czy to nie jest bez sensu? Zamiast bawić się rand'ami, można by skorzystać z chociażby uniqid (no i dla pewności sprawdzić to jeszcze w bazie)...
dr_bonzo
Hmm, no wlasciwie te uniqid + md5 + sprawdzanie sa ok. Bo zwracaja tyle wartosci ze te 10mln to pikus przy nich i szybko limitu nie osiagniesz i latwo o rozne wartosci.

Roznica jest taka - ze w moim przypadku im wiecej userow tym szybciej sprawdzane/wybierane sa nowe ID, a w twoim przypadku im wiecej userow tym wiecej rekordow trzeba sprawdzic smile.gif
.radex
Fakt, ale czy wstawianie do bazy 10000000 rekordów ma sens? Zakładając, że jeden rekord zajmuje 10 bajtów - kupę zmarnowanego miejsca na serwerze. No chyba, że będzie się stopniowo dodawać rekordy (najpierw powiedzmy 1000, a później stopniowo dodawane nowe), ale wtedy nie ma pełnej losowości 0-10000000
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.