![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 130 Pomógł: 0 Dołączył: 18.09.2021 Ostrzeżenie: (0%) ![]() ![]() |
Hej. Mam bazę ok. 2mln rekordów. Każdemu chcę nadać indywidualny, losowy hash skłądający się z 5-ciu cyfr lub małych i dużych znaków. Stworzyłem coś takiego:
Z początku działa szybko (wiadomo, nie ma jeszcze tyle hashy co się powtarzają) ale pod koniec wolniej. Na obecnej maszynie oszacowałem czas wykonywania się tego kody na 50-100 godzin. Jak mogę to zoptywalizować? |
|
|
![]() |
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 623 Pomógł: 144 Dołączył: 22.12.2010 Ostrzeżenie: (0%) ![]() ![]() |
Indeks/indeksy, dac unique dla hash i nie bawic sie w select
A no i jeszcze jaki typ kolumny, varchar? Jeśli tak to jaka długość? Ten post edytował ohm 6.01.2023, 19:44:02 |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 130 Pomógł: 0 Dołączył: 18.09.2021 Ostrzeżenie: (0%) ![]() ![]() |
Myślałem, żeby dać unique ale nie przechodzi ze względu na te pola, które mają NULL lub ieustawiony hash. Tak wygląda struktura tego pola:
Kod `hash` varchar(5) COLLATE utf8_unicode_ci DEFAULT NULL,
|
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 405 Pomógł: 73 Dołączył: 15.07.2014 Ostrzeżenie: (0%) ![]() ![]() |
Przeoranie tego przez PHP zajmie trochę czasu i zje zasobów. Jeżeli tak może być, to spoko, ale ja raczej szukałbym rozwiązania bliżej bazy danych.
Dla MySQL, można skorzystać z takiego czegoś do generowania hasha:
Nie powinno wygenerować tych samych hashy, więc na spokojnie możesz dodać `unique` na kolumnę. Ten post edytował Salvation 6.01.2023, 22:04:22 |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 130 Pomógł: 0 Dołączył: 18.09.2021 Ostrzeżenie: (0%) ![]() ![]() |
Próbowałem i nestety generuje multum powtórzeń. MD5 daje wynik heksadecymalny a zatem pole hash ma 5^16 = 1 048 576 możliwości, mniej niż moja baza danych. Ciąg znaków składający się z 0-9, a-z i A-Z (58 różnych znaków) czyli 58^5 = 656 356 768 (ok. 300 razy za dużo) daje ok 3 powtórzeń przy generowaniu końcowych hashy porcjami po 1000.
Ten post edytował DNMX 6.01.2023, 22:36:15 |
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 405 Pomógł: 73 Dołączył: 15.07.2014 Ostrzeżenie: (0%) ![]() ![]() |
OK, racja. To jeszcze druga próba (IMG:style_emoticons/default/wink.gif)
W sumie to dwie (IMG:style_emoticons/default/biggrin.gif)
Natomiast teraz zdałem sobie z tego sprawę, że `RANDOM_BYTES` może wygenerować znak np. slasha, a to z kolei może nie być poprawnym hashem... Zależy od wytycznych. Ten post edytował Salvation 7.01.2023, 00:26:23 |
|
|
![]()
Post
#7
|
|
Grupa: Zarejestrowani Postów: 6 381 Pomógł: 1116 Dołączył: 30.08.2006 Ostrzeżenie: (0%) ![]() ![]() |
Ja bym poszedł w kierunku https://hashids.org/php/ które generuje stały ciąg dla id. Nie potrzebujesz wtedy select (który w ten sposób zrobiony czyli bazując na offset i limit będzie coraz wolniejszy na kolejnym zbiorze danych) tylko możesz od razu robić update po numerycznym pk.
|
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 324 Pomógł: 105 Dołączył: 7.08.2012 Ostrzeżenie: (0%) ![]() ![]() |
Już to pewnie zdążyłeś załatwić, ale jeszcze dodam coś innego dla zainteresowanych.
base 62 posiada wszystkie cyfry oraz małe i duże litery ASCII. Dla pięcioznakowych id złożonych z tych znaków, ich kombinacji jest w sumie 62^5 = 916132832 Losuj dowolną liczbę od 0 czy 1 do tych 900+ milionów i zamieniaj ją na base 62: Jeszcze można dodawać zera z przodu, gdyby wylosowało niską liczbę i znaków było mniej niż 5. Tym sposobem możesz też zamieniać istniejące id na znaki, ale naturalnie w tym wypadku pojawi się zauważalny wzór w id, jeśli były one po kolei. Ten post edytował kreatiff 17.01.2023, 16:11:31 |
|
|
![]() ![]() |
![]() |
Aktualny czas: 22.09.2025 - 07:31 |