Cześć.
Ostatni wpis wprowadzał nam listy, bazy oraz TTL’a. Dziś postawimy kilka kolejnych kroków, przybliżających nas do poznania Redisa.
Bez przydługich wstępów – zaczynajmy.
Zbiory, podobnie jak w innych rozwiązaniach, to kolekcje unikalnych, nie zachowujących kolejności, elementów. W przypadku Redisa – stringów.
Dwie podstawowe komendy służące do pracy ze zbiorami to SADD i SMEMBERS. Pierwsza z nich dodaje element do zbioru a druga pobiera elementy. Zerknij na kod:
1 2 3 4 5 6 7 8 9 | from redis import Redis redis_connection = Redis(decode_responses=True) redis_connection.sadd("key", "val1") redis_connection.sadd("key", "val2") redis_connection.sadd("key", "val3") print(redis_connection.smembers("key")) |
Który, zgodnie z zasadą działania zbiorów, zwróci za każdym uruchomieniem, elementy w innej kolejności.
Jak łatwo się domyśleć, na zbiorach można wykonywać pewne operacje znane z matematyki np. część wspólna zbiorów, różnica zbiorów itp.
Wspomnianą różnicę zbiorów możemy osiągnąć stosując polecenie SDIFF, część wspólną zbiorów uzyskamy poleceniem SINTER a suma zbiorów to polecenie SUNION.
Gdzie zysk? To co przychodzi mi od razu na myśl to złożoność obliczeniowa tych operacji. Raz że jest dobra a dwa że zawsze jest podana w dokumentacji i np.:
Dostępność tych komend pozwala nam robić operacje na zbiorach bez wyciągania ich z bazy – co oszczędza chociażby pamięć RAM, bo nie musimy trzymać tych elementów w pamięci. Ponadto, operacje typu SDIFF mają warianty (SDIFFSTORE) pozwalając od razu zapisać rezultat pod konkretny klucz, bez konieczności pobierania go do programu.
Redis udostępnia pewna wariację zbiorów, jaką jest posortowany zbiór, czyli sorted set. W tym typie danych, do każdego elementu zbioru, przypisana jest pewna wartość numeryczna, zwana score, używana do zachowania kolejności. Elementy w zbiorze są posortowane rosnąco względem tej wartości. Na potrzeby wpisu będziemy mówić na tę wartość „waga”.
Siłą tych zbiorów jest, ponownie, złożoność obliczeniowa. Podstawowe polecenia oscyluja w okolicach złożoności liniowej.
Komendą ZADD dodajemy elementy a ZRANGE pobieramy je. Zerknij na kod niżej.
1 2 3 4 5 6 7 8 9 10 | from redis import Redis redis_connection = Redis(decode_responses=True) redis_connection.zadd("sorted_set_key", {"key1": 1}) redis_connection.zadd("sorted_set_key", {"key2": 2}) redis_connection.zadd("sorted_set_key", {"key3": 3}) redis_connection.zadd("sorted_set_key", {"key4": 4}) print(redis_connection.zrange("sorted_set_key", 0, -1)) |
Którego efektem jest
['key1', 'key2', 'key3', 'key4']
Jeśli zmodyfikujemy wagi elementów np. na:
1 2 3 4 5 6 7 8 9 10 | from redis import Redis redis_connection = Redis(decode_responses=True) redis_connection.zadd("sorted_set_key", {"key1": 5}) redis_connection.zadd("sorted_set_key", {"key2": 2}) redis_connection.zadd("sorted_set_key", {"key3": 6}) redis_connection.zadd("sorted_set_key", {"key4": 10}) print(redis_connection.zrange("sorted_set_key", 0, -1)) |
To otrzymamy kolejność zgodną z rosnącym porządkowaniem elementów, czyli:
['key2', 'key1', 'key3', 'key4']
Skoro mamy do czynienia z kolekcją, która zachowuje kolejność, to nasuwa się oczywiście pytanie: Co jeśli zdefiniujemy tę samą wartość score kilka razy? Jaka wtedy będzie kolejność?
Spieszę z odpowiedzią: klucze wtedy będą posortowane alfabetycznie. Taką sytuację pokazuje kod:
1 2 3 4 5 6 7 8 9 10 | from redis import Redis redis_connection = Redis(decode_responses=True) redis_connection.zadd("sorted_set_key", {"key2": 1}) redis_connection.zadd("sorted_set_key", {"key1": 1}) redis_connection.zadd("sorted_set_key", {"key4": 1}) redis_connection.zadd("sorted_set_key", {"key3": 1}) print(redis_connection.zrange("sorted_set_key", 0, -1)) |
którego efektem będzie:
['key1', 'key2', 'key3', 'key4']
Komenda ZRANGE pozwala dostać się do wag. Wystarczy, że kod wyżej, nieco zmodyfikujemy, dodając do zrange nazwany parametr withscores o wartości True. Efektem programu po zmianie będzie:
[('key1', 1.0), ('key2', 1.0), ('key3', 1.0), ('key4', 1.0)]
Z ciekawych rzeczy, to istnieją komendy ZPOPMAX oraz ZPOPMIN (oraz ich blokujące odpowiedniki o których naturze wspomniałem w poprzednim artykule). Pozwalają one pobrać element o największej lub najmniejsze wadze.
Poleceniem ZINCRBY możemy zwiększyć wagę konkretnego elementu, ZCOUNT służy do wybrania elementów z pomiędzy zadanego przedziału wag a ZSCORE po prostu zwróci wagę podanego elementu.
Czyli po prostu mapy. Słowniki. Tablice asocjacyjne. Nazw jest dużo, ale idea ta sama – struktura danych przechowująca klucze i odpowiadające im wartości.
1 2 3 4 5 6 7 | from redis import Redis redis_connection = Redis(decode_responses=True) hash_key = 'test_hash' redis_connection.hset(hash_key, 'key', 'value') |
Powyższy kawałek kodu pozwala na stworzenie pod kluczem „test_hash” właśnie słownika, który będzie miał jeden klucz „key” o wartości „value”. Do dodania elementu do hasha używaliśmy polecenia HSET. Jeśli dodawany klucz będzie istniał to zostanie nadpiany. Aby pobrać wszystkie elementy, możemy użyć HGETALL:
1 2 3 | 127.0.0.1:6379> hgetall test_hash 1) "key" 2) "value" |
Do pracy z tym typem danych mamy jeszcze kilka poleceń:
Część czwarta to kolejne kilka metrów wgłąb Redisa, a dokładniej typów danych, jakie on oferuje. Poznaliśmy zbiory oraz ich wariację – zbiory posortowane. Niewątpliwą ich zaletą jest to ze złożoność obliczeniowa większości operacji jest bliska liniowej, co pozwala tworzyć wydajne aplikacje.
Oj daaawnoo mnie tu nie było. Ale wakacje to był czas dużej liczby intensywnych wyjazdów i tak naprawdę, dopiero jakoś… Read More
Cześć! Zapraszam na krótkie podsumowanie kwietnia. Wyjazd do Niemiec A dokładniej pod granicę z Francją. Chrześnica miała pierwszą komunię. Po… Read More
Ostatnio tygodnie były tak bardzo wypełnione, że nie udało mi się napisać nawet krótkiego podsumowanie. Więc dziś zbiorczo podsumuję luty… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W styczniu przeczytałem "Homo Deus: Historia jutra". Książka łudząco podoba do wcześniejszej książki tego… Read More
Cześć! Zapraszam na podsumowanie roku 2023. Książki Zacznijmy od książek. W tym roku cel 35 książek nie został osiągnięty. Niemniej… Read More
Zapraszam na krótkie podsumowanie miesiąca. Książki W grudniu skończyłem czytać Mein Kampf. Nudna książka. Ciekawsze fragmenty można by było streścić… Read More