Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> [MySQL][PHP] Wygenerowanie miliona unikalnych kodów ;)
peter13135
post
Post #1





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


Jak w temacie, w jaki sposób to zrobić ?

kod wygenerować potrafię, dodać go do bazy o dziwo też. Ale ponieważ tego ma być dokładnie milion, to dodanie tego w ten sposób:
  1.  
  2. $kod = generujKod();
  3.  
  4. $istnieje = sprawdzCzyKodIstniejeWBazie();
  5.  
  6. if($istnieje)
  7. {
  8. dodajKodDoBazy();
  9. }
  10.  


Moim zdaniem jest nieco kiepskim pomysłem.

Myślałem o tym, by generować powiedzmy 100 kodów i sprawdzać, które z nich istnieją, myślę,że takie hurtowe wysyłanie pójdzie nieco szybciej.

A co Wy proponujecie ? (IMG:style_emoticons/default/wink.gif)
Go to the top of the page
+Quote Post
zamper
post
Post #2





Grupa: Zarejestrowani
Postów: 156
Pomógł: 17
Dołączył: 11.12.2010
Skąd: Częstochowa

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


A może tak:
  1. $kod = sha1( time().microtime().''.($jakasLosowaLiczba * $jakasInnaLosowaLiczba / $jakasJeszczeInnaLosowaLiczba) );

Potem to puszczasz w pętli która wstawia to do bazy (IMG:style_emoticons/default/smile.gif)

To co masz z funkcji hashującej możesz w dowolnej kolejności mieszać, a kody zawszę będą mieć 40 znaków i będę na 99.(9)% unikalne (IMG:style_emoticons/default/wink.gif)

Ten post edytował zamper 1.09.2012, 10:05:54
Go to the top of the page
+Quote Post
peter13135
post
Post #3





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


Pisałem, że kod potrafię wygenerować. I zrobię to innym sposobem (choćby dlatego, że chce mieć też duże znaki, których sha1 chyba nie posiada)
Problem jest w tym, żebby to wszystko wprowadzić do bazy.

Tablica w php chyba nie przetrzyma miliona rekordów (chyba, że się mylę);
Go to the top of the page
+Quote Post
zamper
post
Post #4





Grupa: Zarejestrowani
Postów: 156
Pomógł: 17
Dołączył: 11.12.2010
Skąd: Częstochowa

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


Cytat
Potem to puszczasz w pętli która wstawia to do bazy

Albo możesz też zrobić zapytania typu:
  1. INSERT INTO kody VALUES ('sfdwfw'), ('wfwfe'), ('wefegf');
Go to the top of the page
+Quote Post
Wazniak96
post
Post #5





Grupa: Zarejestrowani
Postów: 550
Pomógł: 75
Dołączył: 5.06.2012
Skąd: Lębork

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


a myslales o przepuszczeniu tego przez pętle for i dodawac np po 10000 rekordow do bazy .?
Go to the top of the page
+Quote Post
peter13135
post
Post #6





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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




Cytat
INSERT INTO kody VALUES ('sfdwfw'), ('wfwfe'), ('wefegf');


Aby takie zapytanko wygenerować, musze mieć najpierw tablicę z tymi kodami.

Moja super maszyna za pomocą mojego super kodu w PHP, jest w stanie wygenerować jakieś 32k kodów w ciągu pierwszej minuty, zapisując je do tablicy i sprawdzając czy taki kod już istnieje. W kolejnych minuatach będzie pewnie trochę mniej generowanych kodów, bo sprawdzanie (za pomocą in_array) czy kod już istnieje będzie coraz wolniej działało wraz ze wzrostem elementów tablicy. Dlatego poszukuję lepszego rozwiązania.

Cytat
a myslales o przepuszczeniu tego przez pętle for i dodawac np po 10000 rekordow do bazy .?


Myślałem (przecież nawet o tym pisałem) ale wtedy musiałbym łączyć się z bazą i sprawdzać czy kod istnieje, co chyba trwa więcej niż sprawdzenie tego w tablicy php. Z drugiej strony, nie wiem czy jest możliwe utworzenie tak dużej tablicy
Go to the top of the page
+Quote Post
zamper
post
Post #7





Grupa: Zarejestrowani
Postów: 156
Pomógł: 17
Dołączył: 11.12.2010
Skąd: Częstochowa

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


Jeżeli zależy ci na czasie to wymyśl taki algorytm tworzenie kodów, żeby się nie powtarzały.
Potem pętla na zasadzie takiej
  1. $q = 'INSERT INTO kody VALUES ';
  2. for($i=0; $i<1000000; $i++) {
  3. $q .= '("'.generujKod().'"),';
  4. }
  5. $res = $db->query($q);


Do funkcji generujKod możesz przekazać licznik pętli i na podstawie jego utworzyć kod (IMG:style_emoticons/default/wink.gif)

Ten post edytował zamper 1.09.2012, 10:40:41
Go to the top of the page
+Quote Post
peter13135
post
Post #8





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


Niestety, takiego algorytmu stworzyć nie potrafię (który byłby nie do rozszyfrowania przy okazji)
Go to the top of the page
+Quote Post
zamper
post
Post #9





Grupa: Zarejestrowani
Postów: 156
Pomógł: 17
Dołączył: 11.12.2010
Skąd: Częstochowa

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


Cytat
Pisałem, że kod potrafię wygenerować. I zrobię to innym sposobem (choćby dlatego, że chce mieć też duże znaki, których sha1 chyba nie posiada)

No to jak w końcu (IMG:style_emoticons/default/dry.gif)

Algorytm najlepiej zrób na podstawie time, microtime, rand. Potem to wszystko opakuj w sha1. Później możesz tego hasha przetransformować tak, żeby co losowo wygenerowany numerek (albo licznik pętli) robiło większą literę (IMG:style_emoticons/default/smile.gif)

Ten post edytował zamper 1.09.2012, 10:50:44
Go to the top of the page
+Quote Post
peter13135
post
Post #10





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


1.Pisałem, że potrafię wygenerować losowy ciąg znaków (co nazywałem kodem), a nie potafię stworzyć algorytmu do generowania kodów, które by się nie powtarzały.

2. A jak zagwarantujesz, że Twój sposób zwróci mi milion unikalnych kodów ? Pozatym, długość tego mojego kodu ma być równa 10.
Go to the top of the page
+Quote Post
Wazniak96
post
Post #11





Grupa: Zarejestrowani
Postów: 550
Pomógł: 75
Dołączył: 5.06.2012
Skąd: Lębork

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


Kiedys na necie znalazlem taki oto kodzik do tworzenia kodow, moze Ci się kolego przyda (IMG:style_emoticons/default/wink.gif)
  1. $letters = 'abcdefghijklmnopqrstuvwxyz';
  2. $digits = '0123456789';
  3.  
  4. function password_letters($length) {
  5. global $letters;
  6. $array = str_split( $letters );
  7. shuffle( $array );
  8. return implode( array_slice( $array, 0, $length ) );
  9. }
  10.  
  11. function password_digits($length) {
  12. global $digits;
  13. $array = str_split( $digits );
  14. shuffle( $array );
  15. return implode( array_slice( $array, 0, $length ) );
  16. }
  17.  
  18. function password_combined($length) {
  19. global $letters, $digits;
  20. $array = str_split( $letters.$digits );
  21. shuffle( $array );
  22. return implode( array_slice( $array, 0, $length ) );
  23. }
  24.  
  25. $haslo = password_combined(6);
Go to the top of the page
+Quote Post
peter13135
post
Post #12





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


To spytam trochę inaczej. Mogę dać do tabeli w bazie klucz UNIQUE.

Czy jest możliwość, wykonania zapytania typu

[sql]INSERT INTO `codes` VALUES ('kod1'), ('jakiś inny kod'), (...)[/code]
Załóżmy, że ma on 10k kodów i jeśli powiedzmy powtórzy się 100 kodów, to zamiast errora "duplicate entry..." po prostu pominie te duplikaty i doda 9900 kodów ? (IMG:style_emoticons/default/wink.gif)
//edit:: już wiem (IMG:style_emoticons/default/tongue.gif)

edit://
@up, dzięki za chęci, ale się nie przyda.

Ten post edytował peter13135 1.09.2012, 11:04:26
Go to the top of the page
+Quote Post
zamper
post
Post #13





Grupa: Zarejestrowani
Postów: 156
Pomógł: 17
Dołączył: 11.12.2010
Skąd: Częstochowa

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


Mój mały algorytm tworzy co prawda 40 znakowe kody, ale na pewno będę one unikalne, bo są zależne od czasu i kilku liczb losowych oraz ewentualnie licznika pętli

Co do tego, żeby kody miały tylko 10 znaków to już trudniejsza sprawa, ale jeżeli mają one być do potwierdzenia rejestracji konta to 40 a 10 znaków nie robi takiej różnicy, bo i tak kod jest wklepany w linku
Go to the top of the page
+Quote Post
peter13135
post
Post #14





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


Nie mają być do potwierdzenia rejestracji konta, uwierz mi, że do tego celu nie potrzebował bym generować tyle kodów jednocześnie.
Go to the top of the page
+Quote Post
zamper
post
Post #15





Grupa: Zarejestrowani
Postów: 156
Pomógł: 17
Dołączył: 11.12.2010
Skąd: Częstochowa

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


Możesz w takim razie utworzyć zmienną zawierającą wszystkie znaki dostępne w kodzie (a-z A-Z 0-9) i w pętli 10 razy za pomocą liczby losowanej w każdej iteracji wyciągać jakiś znak w tej zmiennej. Wadą tego rozwiązania jest możliwość powtórzenia się kodów.

Ten post edytował zamper 1.09.2012, 11:11:01
Go to the top of the page
+Quote Post
Kużdo
post
Post #16





Grupa: Zarejestrowani
Postów: 181
Pomógł: 14
Dołączył: 4.06.2008

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


Ale kombinujecie. Tworzysz unikalną kolumnę w bazie, a przy wrzucaniu swoich rekordów ignorujesz duplikaty w sposób:
  1. INSERT IGNORE INTO `nazwa_tabeli` ...


A najlepiej jakbyś zrobił sobie formularz do wpisania ilości generowanych rekordów, bo przyda się później. Pod koniec skryptu pobierasz ilość wszystkich rekordów:
  1. SELECT COUNT(`id`) AS `ile` FROM `nazwa_tabeli`


i wyświetlasz sobie ile masz już rekordów, dzięki temu będziesz wiedział ile wpisać w pole formularza jeszcze.
Go to the top of the page
+Quote Post
peter13135
post
Post #17





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


Drogi Kolego zamper. Pisałem w pierwszym poście, o tym że jestem w stanie wygenerować sobie kod (w którymś z następnych postów dodałem, że ma mieć 10 znaków). I z mojego pierwszego postu wynika, że aby utworzyć za pomocą mojego sposobu milion unikalnyh kodów, muszę za każdym razem sprawdzać, czy wcześniej takiego kodu nie wygenerowałem. Zauważ więc, że Twój post nic nowego nie wnosi do tematu.


Zrobiłem kod, który generuje 1000 kodów, następnie wrzuca je do bazy, a baza danych zapisuje tylko te, których jeszcze nie ma w bazie (za pomocą INSERT IGNORE). Działąło by super.... tylko, że baza danych przyjmuje tylko 32768 rekordów. Czy jest na to jakiś sposób ?


@up. O tym, że dowiedziałem się, że jest coś takiego jak INSERT IGNORE dowiedziałęm się jakieś 20 minut temu (patrz post nr 12)

Ten post edytował peter13135 1.09.2012, 11:26:27
Go to the top of the page
+Quote Post
dr_NO
post
Post #18





Grupa: Zarejestrowani
Postów: 197
Pomógł: 15
Dołączył: 10.09.2006
Skąd: Siemianowice Śląskie / Katowice

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


Za MySQL Change Log
Cytat
Support for large databases. We use MySQL Server with databases that contain 50 million records. We also know of users who use MySQL Server with 200,000 tables and about 5,000,000,000 rows.

Jakiego typu masz pola w bazie? Może używasz typu który ma ograniczenia?
Go to the top of the page
+Quote Post
Kużdo
post
Post #19





Grupa: Zarejestrowani
Postów: 181
Pomógł: 14
Dołączył: 4.06.2008

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


Nie zauważyłem tego (IMG:style_emoticons/default/wink.gif)

Przyjmuje Ci MAKS 32768 rekordów, czy w jednej paczce tyle? Bo nie do końca zrozumiałem to co napisałeś. Miałem w sumie wrzucić tutaj przykładowy kod do poprzedniego postu, ale nie wiem czy jest Ci jeszcze potrzebny.
Go to the top of the page
+Quote Post
peter13135
post
Post #20





Grupa: Zarejestrowani
Postów: 1 447
Pomógł: 191
Dołączył: 26.03.2008

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


id to big int

typ bazy to MyIsam, przed chwilą miałem innoDb, ale na obu mam ten limit.

Paczki mam po 10k

Baza ma limit ~33k (2^15)

Ten post edytował peter13135 1.09.2012, 11:35:22
Go to the top of the page
+Quote Post

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

 



RSS Aktualny czas: 23.08.2025 - 18:20