Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [PHP] Losowe numery i sprawdzanie z bazą danych
looimaster
post 22.05.2008, 12:42:41
Post #1





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 26.01.2008

Ostrzeżenie: (0%)
-----


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?
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 13)
Cezar708
post 22.05.2008, 12:50:54
Post #2





Grupa: Zarejestrowani
Postów: 1 116
Pomógł: 119
Dołączył: 10.05.2005
Skąd: Poznań

Ostrzeżenie: (0%)
-----


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

Ten post edytował Cezar708 22.05.2008, 12:51:55
Go to the top of the page
+Quote Post
looimaster
post 22.05.2008, 12:55:25
Post #3





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 26.01.2008

Ostrzeżenie: (0%)
-----


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.
Go to the top of the page
+Quote Post
phpion
post 23.05.2008, 09:26:42
Post #4





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




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
Go to the top of the page
+Quote Post
Demio
post 23.05.2008, 09:36:41
Post #5





Grupa: Zarejestrowani
Postów: 14
Pomógł: 1
Dołączył: 22.05.2008

Ostrzeżenie: (0%)
-----


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ę.
Go to the top of the page
+Quote Post
.radex
post 23.05.2008, 09:52:09
Post #6





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


ew. możesz hasz skrócić z 32znaków do 8 za pomocą np. substr.

substr('tutaj_hasz', 0, 8);


--------------------
blog | Tadam — minutnik do Pomodoro na Maka :)
Go to the top of the page
+Quote Post
looimaster
post 23.05.2008, 11:47:14
Post #7





Grupa: Zarejestrowani
Postów: 8
Pomógł: 0
Dołączył: 26.01.2008

Ostrzeżenie: (0%)
-----


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.

Ten post edytował looimaster 23.05.2008, 11:50:55
Go to the top of the page
+Quote Post
.radex
post 23.05.2008, 12:24:08
Post #8





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


no więc dlaczego nie możesz użyć uniqid(), albo md5(microtime()) ?

Trza sobie ułatwiać życie winksmiley.jpg


--------------------
blog | Tadam — minutnik do Pomodoro na Maka :)
Go to the top of the page
+Quote Post
dr_bonzo
post 23.05.2008, 14:29:49
Post #9





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


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.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
.radex
post 23.05.2008, 15:59:50
Post #10





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


No pewnie, ale rand()'y też nie.


--------------------
blog | Tadam — minutnik do Pomodoro na Maka :)
Go to the top of the page
+Quote Post
dr_bonzo
post 23.05.2008, 17:59:51
Post #11





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


rand() same w sobie nie, ale on sprawdzal czy aby mu sie nie powtarzaja


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
.radex
post 23.05.2008, 18:02:56
Post #12





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


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


--------------------
blog | Tadam — minutnik do Pomodoro na Maka :)
Go to the top of the page
+Quote Post
dr_bonzo
post 23.05.2008, 18:53:19
Post #13





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


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


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
.radex
post 23.05.2008, 19:03:31
Post #14





Grupa: Zarejestrowani
Postów: 1 657
Pomógł: 125
Dołączył: 29.04.2006

Ostrzeżenie: (0%)
-----


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


--------------------
blog | Tadam — minutnik do Pomodoro na Maka :)
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 18.07.2025 - 01:44