CQL II - Instytut Informatyki Teoretycznej i Stosowanej
Transkrypt
CQL II - Instytut Informatyki Teoretycznej i Stosowanej
Baza danych Cassandra. Język CQL. Baza danych Cassandra. Język CQL. Technologie Zarządzania Treścią dr inż. Robert Perliński [email protected] Politechnika Częstochowska Instytut Informatyki Teoretycznej i Stosowanej 10 stycznia 2017 1/56 Plan prezentacji 1 Manipulacja na danych SELECT INSERT UPDATE DELETE BATCH 2 Drugorzędne indeksy 3 Perspektywy zmaterializowane 4 Funkcje Funkcje skalarne Funkcje agregujące 5 Wsparcie dla formatu JSON 6 Źródła Baza danych Cassandra. Język CQL. 2/56 SELECT select_statement ::= SELECT [ JSON | DISTINCT ] ( select_clause | '*' ) FROM table_name [ WHERE where_clause ] [ GROUP BY group_by_clause ] [ ORDER BY ordering_clause ] [ PER PARTITION LIMIT (integer | bind_marker) ] [ LIMIT (integer | bind_marker) ] [ ALLOW FILTERING ] select_clause ::= selector [ AS identifier ](',' selector [AS identifier] )* selector ::= column_name | term | CAST '(' selector AS cql_type ')' | function_name '(' [ selector ( ',' selector )* ] ')' | COUNT '(' '*' ')' where_clause ::= relation ( AND relation )* relation ::= column_name operator term '(' column_name (',' column_name)* ')' operator tuple_literal TOKEN '(' column_name (',' column_name)* ')' operator term operator ::= '=' | '<' | '>' | '<=' | '>=' | '!=' | IN | CONTAINS | CONTAINS KEY group_by_clause ::= column_name ( ',' column_name )* ordering_clause ::= column_name [ ASC | DESC ] ( ',' column_name [ ASC|DESC ] )* Baza danych Cassandra. Język CQL. 3/56 SELECT SELECT: odczytuje jedną lub więcej kolumn z jednego lub więcej wiersza tabeli, wynikiem są wiersze, które spełniały wymagania podane w zapytaniu, każdy wiersz zwraca te dane, które były określone w zapytaniu, funkcje zawierające agregacje mogą być zastosowane do wyników. Zapytanie SELECT: zawiera przynajmniej klauzulę SELECT i nazwę tabeli, na której odbywa się zapytanie, CQL nie wykonuje złączeń ani podzapytań - zapytanie odnosi się do pojedynczej tabeli, zwykle zawiera również klauzulę WHERE, może również zawierać klauzule ORDER BY i LIMIT, zapytania wymagające filtrowania mogą wykonane po dodaniu opcji ALLOW FILTERING. Baza danych Cassandra. Język CQL. 4/56 SELECT - klauzula wyboru Klauzula wyboru: określa, które kolumny z tabeli chcemy pobrać i zwrócić, określa, jakie transformacje na danych chcemy wykonać, składa się z oddzielonej przecinkami listy selektorów albo znaku ’*’, Selektor może być: nazwą kolumny aby pobrać dane tej kolumny, nazwą (ang. term), która jest zwykle zagnieżdżona wewnątrz innych selektorów, np. wywołania funkcji, rzutowaniem, które pozwala konwertować zagnieżdżony selektor do innego (kompatybilnego) typu, wywołaniem funkcji, której argumenty same w sobie są selektorami, wywołaniem funkcji COUNT(*) zliczającej wszystkie niepuste wiersze. Baza danych Cassandra. Język CQL. 5/56 SELECT - klauzula wyboru, aliasy Aliay w CQL Każdy selektor najwyższego poziomu może mieć alias. Alias określa nazwę kolumny w wynikowych danych. Przykład: > SELECT count(*) FROM osoba; count ------2 > SELECT count(*) AS "Liczba osób" FROM osoba; Liczba osób ------------2 Obecnie (CQL wersja 3.4.3), poza tabelą wynikową aliasy nie są rozpoznawane gdziekolwiek indziej (WHERE, ODRER BY, ...), trzeba używać oryginalnej nazwy kolumny... Baza danych Cassandra. Język CQL. 6/56 SELECT - klauzula wyboru, funkcje TTL i WRITETIME W klauzuli wyboru danych można używać dwóch specjalnych funkcji: funkcje zwracają meta-informacje przechowywane wewnętrznie dla każdej kolumny, obie przyjmują jeden parametr, który musi być nazwą kolumny. WRITETIME() - zwraca punkt czasowy Przykłady: INSERT INTO osoba (id, imie , nazwisko ) VALUES ( 3, 'Halina', 'Mieczynska') USING TTL 3600; cqlsh:mpk> SELECT WRITETIME(imie) FROM osoba ; writetime(imie) -----------------1480086070686855 1480424647503029 1482160168249122 Baza danych Cassandra. Język CQL. 7/56 SELECT - klauzula wyboru, funkcje TTL i WRITETIME W klauzuli wyboru danych można używać dwóch specjalnych funkcji: funkcje zwracają meta-informacje przechowywane wewnętrznie dla każdej kolumny, obie przyjmują jeden parametr, który musi być nazwą kolumny. TTL() - zwraca liczbę sekund pozostałą do wygaśnięcia danych z podanej kolumny albo null, Przykłady: SELECT TTL(imie), TTL(nazwisko) FROM osoba ; cqlsh:mpk> SELECT TTL(imie), TTL(nazwisko) FROM osoba ; ttl(imie) | ttl(nazwisko) -----------+--------------null | null null | null 3368 | 3368 Baza danych Cassandra. Język CQL. 8/56 SELECT - klauzula WHERE Klauzula WHERE: określa, które wiersze mają być zwrócone, warunek musi być utworzony na kolumnach klucza głównego i/lub kolumn z indeksem, nie wszystkie relacje/warunki są dopuszczalne, np. operator IN nie jest dopuszczalny na kluczu partycjonowania. co więcej, dla danej wartości klucza partycjonowania, warunki dla kolumn grupujących muszą zwracać ciągły zbiór wierszy. Baza danych Cassandra. Język CQL. 9/56 SELECT - klauzula GROUP BY Klauzula GROUP BY: pozwala połączyć w jeden wiersz wszystkie wybrane wiersze, które mają takie same wartości w określonym zbiorze kolumn, grupowanie wierszy jest tylko możliwe dla poziomu kucza partycjonowania albo dla poziomu kolumn grupujących, jako argumenty przyjmuje tylko kolumny z klucza głównego, w kolejności w jakiej występują w kluczu głównym, jeśli kolumna klucza głównego występuje w warunku równościowym, to nie jest wymagane aby była w klauzuli GROUP BY, funkcje agregacji wygenerują osobne wartości dla każdej grupy, bez klauzuli GROUP BY funkcje agregacji wygenerują pojedynczą wartość dla każdego wiersza, wybór kolumny będącej w klauzuli GROUP BY bez udziału funkcji agregującej zwróci pierszy wiersz z każdej grupy. Baza danych Cassandra. Język CQL. 10/56 SELECT - sortowanie wyników Klauzula ORDER BY - sortowanie wyników: pozwala określić porządek zwracanych wyników, podajemy nazwy kolumn przy każdej podając porządek rosnący lub malejący (ASC / DESC ), sortowanie jest możliwe na razie tylko po kolumnach grupujących. Baza danych Cassandra. Język CQL. 11/56 SELECT - limitowanie wyników Opcja LIMIT ogranicza liczbę zwróconych przez zapytanie wierszy. Opcja PER PARTITION LIMIT ogranicza liczbę wierszy zwróconą przez zapytanie dla danej partycji. Oba te ograniczenia można mogą być użyte w tym samym czasie. Baza danych Cassandra. Język CQL. 12/56 SELECT - kilka przykładów CREATE TABLE aktorzy ( id int PRIMARY KEY, imie text, nazwisko text, data_ur date, narodowosc text ); SELECT * FROM aktorzy; id | data_ur | imie | narodowosc | nazwisko ----+------------+----------+------------+------------5 | null | Jennifer | null | Aniston 1 | 1956-07-09 | Tom | USA | Hanks 2 | 1962-01-17 | Jim | Kanada | Carrey 4 | 1962-06-13 | Cezary | Polska | Pazura 3 | 1961-07-17 | Zbigniew | Polska | Zamachowski Baza danych Cassandra. Język CQL. 13/56 SELECT - kilka przykładów SELECT * FROM aktorzy; SELECT count(*) FROM aktorzy; // agregacja bez klucza partycjonowania... // jedno imię na trzy różne sposoby... SELECT min(imie) as "Imię aktora" FROM aktorzy; Imię aktora ------------Cezary SELECT id,imie as "Imię aktora" FROM aktorzy WHERE id=1; id | Imię aktora ----+------------1 | Tom SELECT imie as "Imię aktora" FROM aktorzy LIMIT 1; Imię aktora ------------Jennifer Baza danych Cassandra. Język CQL. 14/56 SELECT - kilka przykładów SELECT * FROM aktorzy WHERE token(id)>token(1); id | data_ur | imie | narodowosc | nazwisko ----+------------+----------+------------+------------2 | 1962-01-17 | Jim | Kanada | Carrey 4 | 1962-06-13 | Cezary | Polska | Pazura 3 | 1961-07-17 | Zbigniew | Polska | Zamachowski SELECT * FROM aktorzy WHERE id IN (1,3); id | data_ur | imie | narodowosc | nazwisko ----+------------+----------+------------+------------1 | 1956-07-09 | Tom | USA | Hanks 3 | 1961-07-17 | Zbigniew | Polska | Zamachowski SELECT * FROM aktorzy WHERE data_ur>'1962-01-01' ALLOW FILTERING; id | data_ur | imie | narodowosc | nazwisko ----+------------+--------+------------+---------2 | 1962-01-17 | Jim | Kanada | Carrey 4 | 1962-06-13 | Cezary | Polska | Pazura Baza danych Cassandra. Język CQL. 15/56 SELECT - kilka przykładów CREATE TABLE filmy ( gatunek text, produkcja text, tytul text, rezyser text, premiera date, cena float, PRIMARY KEY ((gatunek, produkcja), tytul) ); SELECT * FROM filmy; gatunek | produkcja | tytul | cena | premiera | rezyser -----------+-----------+--------------------------+-------+------------+-------dramat | Japonia | 7 samurajów | 28 | 1954-04-26 | ... komedia | Polska | Miś | null | 1981-05-04 | ... komedia | Polska | Ryś | 63.15 | 2007-02-09 | ... komedia | Polska | Sami swoi | 29 | 1967-09-15 | ... dramat | Polska | Tato | 21.99 | 1995-12-14 | ... dramat | USA | Cast Away - poza światem | 25.5 | 2000-12-07 | ... dramat | USA | Forrest Gump | 21.99 | 1994-06-23 | ... dramat | USA | Truman Show | 26.9 | 1998-06-01 | ... melodramat | USA | La La Land | null | 2016-08-31 | ... komedia | USA | Bruce Wszechmogący | 32.35 | 2003-05-14 | ... Baza danych Cassandra. Język CQL. 16/56 SELECT - kilka przykładów // wszystko z limitem SELECT * FROM filmy LIMIT 3; // lista filmów, po 3 pierwsze z każdej partycji SELECT * FROM filmy PER PARTITION LIMIT 3; // lista filmów ale tylko jeden z kazdej partycji a w sumie maksymalnie 6 SELECT * FROM filmy PER PARTITION LIMIT 1 LIMIT 6; // lista gatunków filmowych ale .... SELECT DISTINCT gatunek, produkcja FROM filmy; // dramaty poskie albo japońkie SELECT * FROM filmy WHERE gatunek ='dramat' AND produkcja IN ('Japonia', 'Polska', 'USA'); // różne ceny..., średnie, itd. SELECT count(cena) as "Liczba filmów", avg(cena) as "ŚredniaCena" FROM filmy WHERE gatunek='komedia' AND produkcja='Polska'; // czas zapisu danych i ich ważności (TTL) w kolumnach rezyser i cena SELECT WRITETIME(rezyser),WRITETIME(cena) FROM filmy; SELECT TTL(rezyser),TTL(cena) FROM filmy; Baza danych Cassandra. Język CQL. 17/56 INSERT insert_statement ::= names_values json_clause names ::= ::= ::= INSERT INTO table_name ( names_values | json_clause ) [ IF NOT EXISTS ] [ USING update_parameter ( AND update_parameter )* ] names VALUES tuple_literal JSON string [ DEFAULT ( NULL | UNSET ) ] '(' column_name ( ',' column_name )* ')' INSERT: zapisuje dane jednej lub więcej kolumn w tabeli, ponieważ wiersz jest identyfikowany przez klucz człówny, trzeba wyspecyfikować przynajmniej kolumny, które go tworzą, dwa rodzaje wstawiania danych: podajemy listę kolumn i ich zawartość w VALUES, podejmy wartość z formacie JSON, wszystkie operacje są atomowe i izolowane, INSERT nie wspiera liczników, a UPDATE wspiera. Baza danych Cassandra. Język CQL. 18/56 INSERT, UPDATE - parametry aktualizacji Polecenia UPDATE, INSERT (oraz DELETE i BATCH dla TIMESTAMP) mają następujące parametry aktualizacji: TIMESTAMP - ustawia punkt czasowy dla operacji. Jeśli nie ustawiony, zostanie użyty bieżący punkt czasowy rozpoczęcia wykonywania polecenia. To jest domyślne działanie i zwykle wystarcza. TTL - określa opcję Time To Live (w sekundach) dla wstawianych wartości. TTL dotyczy konkretnych wartości, nie samych kolumn. Wartość TTO ustawiona na 0 oznacza brak TTL. Baza danych Cassandra. Język CQL. 19/56 INSERT - przykłady Przykłady INSERT: CREATE TABLE filmy ( tytul text PRIMARY KEY, rezyser text, glowny_aktor text, rok int); INSERT INTO filmy ( tytul, rezyser, glowny_aktor, rok ) VALUES ( 'Forrest Gump', 'Robert Zemeckis', 'Tom Hanks', 1994 ); INSERT INTO filmy (tytul, rezyser, rok ) VALUES ( 'Pan Tadeusz', 'Andrzej Wajda', 1999); INSERT INTO filmy JSON '{ "tytul":"Siedmiu samurajów", "rezyser":"Akira Kurosawa", "rok": 1954 }'; SELECT * FROM filmy; tytul | glowny_aktor | rezyser | rok -------------------+--------------+-----------------+-----Siedmiu samurajów | null | Akira Kurosawa | 1954 Pan Tadeusz | null | Andrzej Wajda | 1999 Forrest Gump | Tom Hanks | Robert Zemeckis | 1994 Baza danych Cassandra. Język CQL. 20/56 INSERT Inaczej niż w SQL, INSERT domyślnie nie sprawdza istnienia danych w wstawianym wierszu: dane są dodawane albo aktualizowane, nie ma sposobu na sprawdzenie, która z tych operacji miała miejsce, INSERT INTO filmy JSON '{"tytul":"Miś", "rezyser":"Stanisław Tym", "rok":1980}'; INSERT INTO filmy JSON '{"tytul":"Miś", "rezyser":"Stanisław Bareja", "glowny_aktor":"Stanisław Tym", "rok": 1980}'; tytul | glowny_aktor | rezyser | rok -------------------+---------------+-------------------+-----Miś | null | Stanisław Tym | 1980 ... Miś | Stanisław Tym | Stanisław Bareja | 1980 INSERT INTO filmy JSON '{"tytul":"Miś", "rezyser":"Stanisław Bareja", "glowny_aktor": "Stanisław Tym", "rok": 1980}' IF NOT EXISTS; Warunek IF NOT EXISTS powoduje dodawanie danych, gdy takie jeszcze nie istnieją. Opcja ta pociąga za sobą dodatkowy koszt wykonania polecenia powinna być oszczędnie używana. Opcji DEFAULT też nie udało się uruchomić. Baza danych Cassandra. Język CQL. 21/56 UPDATE update_statement ::= update_parameter ::= assignment ::= simple_selection ::= condition ::= UPDATE table_name [ USING update_parameter ( AND update_parameter )* ] SET assignment ( ',' assignment )* WHERE where_clause [ IF ( EXISTS | condition ( AND condition )*) ] ( TIMESTAMP | TTL ) ( integer | bind_marker ) simple_selection '=' term | column_name '=' column_name ( '+' | '-' ) term | column_name '=' list_literal '+' column_name column_name | column_name '[' term ']' | column_name '.' ‘field_name simple_selection operator term UPDATE: aktualizuje jedną lub więcej kolumn dla podanego wiersza danej tabeli, klauzula WHERE określa aktualizowany wiersz, musi zawierać wszystkie kolumny tworzące klucz główny, pozostałe kolumny (nie będące kluczem głównym) są aktualizowane/ustawiane przy użyciu SET, Baza danych Cassandra. Język CQL. 22/56 UPDATE UPDATE: inaczej niż SQL, UPDATE nie sprawdza czy aktualizowany wiersz istnieje (z wyjątkiem warunku IF), wiersz jest tworzony jeśli nie istniał albo aktualizowany jeśli istniał. Nie mamy informacji czy wiersz został utworzony czy zaktualizowany. Warunek IF pozwala określić, że wiersze nie będą aktualizowane chyba, że spełniony będzie podany warunek. Opcja ta pociąga za sobą dodatkowy koszt wykonania polecenia - powinna być oszczędnie używana. Wszystkie aktualizacje wykonywane na tym samym kluczu partycjonowania są atomowe i izolowane. Baza danych Cassandra. Język CQL. 23/56 UPDATE - przypisywanie wartości UPDATE - przypisywanie wartości (ang. assigment): c = c + 3 - używane w celu inkrementacji/dekrementacji liczników; nazwy kolumn przed i za znakiem ’=’ muszą być takie same. Dostępne tylko dla liczników i jest to jedyna opcja aktualizacji, którą można robić na licznikach. id = id + <wybrana-kolekcja> oraz id[wartosc1] = wartosc2 używane dla kolekcji. id.pole = 7 - ustawia wartość pola typu użytkownika, które nie jest typu frozen. Baza danych Cassandra. Język CQL. 24/56 UPDATE - kilka przykładów UPDATE filmy USING TTL 120 SET premiera = '1981-04-04' WHERE gatunek='komedia' AND produkcja = 'Polska' AND tytul = 'Miś'; SELECT tytul, premiera,TTL(premiera) FROM filmy; tytul | premiera | ttl(premiera) --------------------+------------+--------------7 samurajów | 1954-04-26 | null Miś | 1981-04-04 | 48 ... tytul | premiera | ttl(premiera) --------------------+------------+--------------7 samurajów | 1954-04-26 | null Miś | null | null UPDATE filmy SET cena=25.5, premiera='2000-12-07', rezyser='Robert Zemeckis' WHERE gatunek='dramat' AND produkcja='USA' AND tytul='Cast Away - poza światem'; ALTER TABLE filmy2 ADD aktorzy map <int,text>; UPDATE filmy SET aktorzy = {1:'Tom Hanks'} WHERE gatunek='dramat' AND produkcja='USA' AND tytul='Forrest Gump'; Baza danych Cassandra. Język CQL. 25/56 DELETE delete_statement ::= DELETE [ simple_selection ( ',' simple_selection ) ] FROM table_name [ USING update_parameter ( AND update_parameter )* ] WHERE where_clause [ IF ( EXISTS | condition ( AND condition )*) ] DELETE: usuwa kolumny i wiersze, jeśli podano nazwy kolumn, to usuwane są tylko dane w tych kolumnach, jeśli nazwy kolumn pominięto, to usuwane są całe wiersze, klauzula WHERE określa, które wiersze mają być usunięte, wiele wierszy może być jednocześnie usuniętych dzięki operatorowi IN, zakres wierszy można usunąć też używająć operatorów nierównościowych, np. >=, Baza danych Cassandra. Język CQL. 26/56 DELETE DELETE: wspiera opcję TIMESTAMP, semantyka jak w INSERT i UPDATE, wszystkie usunięcia odbywające się dla tego samego klucza partycji są atomowe i izolowane, Warunek IF pozwala podać warunek, czy wiersze będą usuwane. Opcja ta pociąga za sobą dodatkowy koszt wykonania polecenia powinna być oszczędnie używana. Przykłady: // usuwa całą partycję, wiersze spełniające warunek klucza partycjonującego DELETE FROM filmy WHERE gatunek='sci-fi' AND produkcja='USA'; // usuwa dwie dane jednego wiersza: premierę i cenę DELETE premiera, cena FROM filmy WHERE gatunek ='dramat' AND produkcja ='Japonia' AND tytul ='7 samurajów'; // BŁĄD! próba usuwania danej klucza głównego DELETE premiera, tytul FROM filmy WHERE gatunek ='dramat' AND produkcja ='Japonia'; Baza danych Cassandra. Język CQL. 27/56 BATCH batch_statement ::= BEGIN [ UNLOGGED | COUNTER ] BATCH [ USING update_parameter ( AND update_parameter )* ] modification_statement ( ';' modification_statement )* APPLY BATCH modification_statement ::= insert_statement | update_statement |delete_statement BATCH - operacje wykonywane grupowo: polecenie grupuje wiele poleceń modyfikujących dane (INSERT, UPDATE, DELETE) w jedno polecenie, wykorzystywane w wielu celach: zmniejsza ruch w sieci między klientem a serwerem (między serwerem koordynującym a replikami) kiedy wykonuje wiele aktualizacji, wszystkie aktualizacje danych wykonywane w BATCH, które mają jeden klucz partycjonowania są izolowane, domyślnie wszystkie operacje wykonywane grupowo są wykonywane jako zalogowany żeby zapewnić wykonanie wszystkich poleceń z grupy (albo żadnego), opcja COUNTER pozwala na grupowanie operacji na licznikach. Baza danych Cassandra. Język CQL. 28/56 BATCH BATCH - operacje wykonywane grupowo: to nie to samo co transakcje w SQL, jeśli nie podano punktu czasowego, wszystkie operacje zostaną wykonane z tym samym punktem czasowym (wygenerowanym automatycznie albo podanym globalnie na poziomie BATCH). Operacje grupowe bez logowania (ang. UNLOGGED): domyślnie Cassandra loguje wszystkie operacje grupowe co gwarantuje pewność wykonania wszystkich albo żadnego, izolowanie operacji odbywa się tylko w obrębie jednej partycji, atomowość operacji grupowych jest kosztowna, jeśli odbywa się na wielu partycjach, w takim wypadku można porzucić logowanie wykonywanych opercji i ich atomowość dzięki opcji UNLOGGED, opcja UNLOGGED może się skończyć wykonaniem tylko części poleceń z grupy. Baza danych Cassandra. Język CQL. 29/56 BATCH - przykład Polecenie BATCH warto wywołać w postaci zapisanej w skrypcie, np.: cqlsh:lab11> SOURCE ’skrypt.cql’ skrypt.cql BEGIN BATCH INSERT INTO aktorzy (id, imie, nazwisko, data_ur) VALUES (7, 'Emma', 'Stone', '1988-11-06'); DELETE FROM filmy WHERE gatunek='dramst' AND produkcja='Polska'; INSERT INTO filmy (gatunek, produkcja, tytul, rezyser, premiera) VALUES ('melodramat', 'USA', 'La La Land', 'Damien Chazelle', '2016-08-31'); APPLY BATCH; Baza danych Cassandra. Język CQL. 30/56 Drugorzędne indeksy CQL wspiera tworzenie dodatkowych (drugorzędnych) indeksów na tabelach (ang. secondary indexes). Zapytania wykonywane na tabelach mogą z tych indeksów korzystać. Nazwa indeksu może być następująca: index_name ::= re('[a-zA-Z_0-9]+') do utworzenia indeksu mamy polecenie CREATE INDEX: create_index_statement ::= CREATE [ CUSTOM ] INDEX [IF NOT EXISTS] [index_name] ON table_name '(' index_identifier ')' [ USING string [ WITH OPTIONS = map_literal ] ] index_identifier ::= column_name | ( KEYS | VALUES | ENTRIES | FULL ) '(' column_name ')' Baza danych Cassandra. Język CQL. 31/56 Dodatkowe indeksy Polecenie CREATE INDEX: tworzy nowy indeks (drugorzędny) dla istniejącej kolumny dla podanej tabeli, nazwa indeksu może być podana przed słowem kluczowym ON, jeśli kolumna zawiera już dane, to będą one zindeksowane asynchronicznie, nowe dane dodawane do kolumny z indeksem są indeksowane automatycznie w czasie wstawiania, zwróci błąd, jeśli będziemy próbowali tworzyć już istniejący indeks, chyba, że użyjemy opcji IF NOT EXISTS, wtedy jest no-op, Polecenie CREATE INDEX dla map: można tworzyć indeksy zarówno dla kluczy jak i dla wartości, umieszczenie nazwy kolumny wewnątrz funkcji keys() utworzy indeks na kluczach, pozwoli to na użycie CONTAINS KEY w klauzuli WHERE, bez funkcji keys() indeks będzie utworzony na wartościach mapy. Baza danych Cassandra. Język CQL. 32/56 Dodatkowe indeksy - przykłady CREATE INDEX userIndex ON NerdMovies (user); CREATE INDEX ON Mutants (abilityId); CREATE INDEX ON users (keys(favs)); CREATE CUSTOM INDEX ON users (email) USING 'path.to.the.IndexClass'; CREATE CUSTOM INDEX ON users (email) USING 'path.to.the.IndexClass' WITH OPTIONS = {'storage': '/mnt/ssd/indexes/'}; Baza danych Cassandra. Język CQL. 33/56 Usuwanie indeksu drop_index_statement ::= DROP INDEX [ IF EXISTS ] index_name Polecenie DROP INDEX: usuwa indeks o podanej nazwie, nazwa indeksu może uwzględniać również przestrzeń kluczy, zwraca błąd jeśli indeks o podanej nazwie nie istnieje, chyba, że podano IF EXISTS wtedy jest no-op. Baza danych Cassandra. Język CQL. 34/56 Perspektywy zmaterializowane Perspektywy zmaterializowane (ang. materialized views) są tworzone za pomocą polecenia CREATE MATERIALIZED VIEW: create_materialized_view_statement ::= CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] view_name AS select_statement PRIMARY KEY '(' primary_key ')' WITH table_options gdzie nazwa perwspektywy to view_name ::= re('[a-zA-Z_0-9]+') Próba utworzenia perspektywy już istniejącej skończy się błędem chyba, że użyto opcji IF NOT EXISTS, wtedy działanie skończy się brakiem operacji (no-op). Baza danych Cassandra. Język CQL. 35/56 Perspektywy zmaterializowane Polecenie CREATE MATERIALIZED VIEW: tworzy nową perspektywę zmaterializowaną, każda taka perspektywa jest zbiorem wierszy odpowiadających wierszom z tabeli bazowej (pierwotnej) umieszczonej w klauzuli SELECT. Perspektywa zmaterializowana nie może być modyfikowana bezpośrednio. Zmiana tabeli bazowej wywołuje odpowiednie zmiany w perspektywie. Tworzenie perspektywy ma trzy główne części: zapytanie SELECT, które określa dane uwzględnione w perspektywie, definicja PRIMARY KEY, opcje. Baza danych Cassandra. Język CQL. 36/56 Perspektywy zmaterializowane - przykład Perspektywy zmaterializowane - przykład: CREATE MATERIALIZED VIEW monkeySpecies_by_population AS SELECT * FROM monkeySpecies WHERE population IS NOT NULL AND species IS NOT NULL PRIMARY KEY (population, species) WITH comment='Allow query by population instead of species'; CREATE MATERIALIZED VIEW polskie_dramaty AS SELECT tytul, gatunek, produkcja, premiera, rezyser FROM filmy WHERE gatunek ='dramat' AND tytul IS NOT NULL AND produkcja='Polska' PRIMARY KEY (tytul, gatunek, produkcja); Baza danych Cassandra. Język CQL. 37/56 Perspektywy zmaterializowane - zapytanie SELECT określa, co z tabeli bazowej będzie uwzględnione w widoku. ma wiele ograniczeń w klauzuli SELECT: można wybierać tylko kolumny z tabeli bazowej, czyli... nie można używać żadnych funkcji, rzutowania itp., nie są wspierane aliasy, można używać symbolu * dla oznaczenia wszystkich kolumn, statyczne kolumny nie mogą być uwzględnione w perspektywie, stąd, jeśli tabela ma kolumny statyczne, to nie można użyć SELECT *, ma wiele ograniczeń w klauzuli WHERE: nie można używać zmiennych związanych (bind marker), kolumny, które nie są częścią klucza głównego mogą być ograniczane tylko za pomocą IS NOT NULL, kolumny, które mają być częścią klucza głównego perspektywy nie mogą być puste, muszą mieć zawsze przynajmniej ograniczenie IS NOT NULL; mogą mieć dowolne inne ale jedno przynajmniej muszą mieć, nie może zawierać klauzul: ORDER BY, LIMIT i ALLOW FILTERING. Baza danych Cassandra. Język CQL. 38/56 Perspektywy zmaterializowane - klucz główny Perspektywa musi posiadać klucz główny, który spełnia określone kryteria: musi posiadać wszystkie kolumny klucza głównego tabeli bazowej, to zapewnia, że każdy wiersz perspektywy odpowiada dokładnie jednemu wierszowi tabeli, może posiadać tylko jedną kolumnę, która nie jest kolumną klucza głównego tabeli bazowej. Mamy przykładową tabelę t: CREATE TABLE t ( k int, c1 int, c2 int, v1 int, v2 int, PRIMARY KEY (k, c1, c2) ) Baza danych Cassandra. Język CQL. 39/56 Perspektywy zmaterializowane - klucz główny, przykłady Perspektywy możliwe do utworzenia na bazie tabeli t, poprawne: CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL PRIMARY KEY (c1, k, c2) CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL PRIMARY KEY (v1, k, c1, c2) Perspektywy niemożliwe do utworzenia, niepoprawne: // Błąd: nie można uzwględnić jednocześnie dwóch kolumn v1 i v2, // obie te kolumny nie są częścią klucza głównego tabeli bazowej CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM t WHERE k IS NOT NULL AND c1 IS NOT NULL AND c2 IS NOT NULL AND v1 IS NOT NULL PRIMARY KEY (v1, v2, k, c1, c2) // Błąd: klucz perspektywy nie uwzględnia kolumny k, // która jest cześcią klucza głównego tabeli t CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM t WHERE c1 IS NOT NULL AND c2 IS NOT NULL PRIMARY KEY (c1, c2) Baza danych Cassandra. Język CQL. 40/56 Perspektywy zmaterializowane - opcje Perspektywy zmaterializowane są wewnętrznie zaimplementowane na bazie tabeli. Mają takie same opcje jak przy tworzeniu tabel. Baza danych Cassandra. Język CQL. 41/56 Pozostałe operacje na perspektywach Zmiana perspektywy: Po utworzeniu perspektywy można zmienić jej opcje. Używamy polecenia ALTER MATERIALIZED VIEW alter_materialized_view_statement ::= ALTER MATERIALIZED VIEW view_name WITH table_options Opcje są takie same jak przy tworzeniu tabel. Usuwanie perspektywy: Do usuwania perspektywy używamy polecenia DROP MATERIALIZED VIEW: drop_materialized_view_statement ::= DROP MATERIALIZED VIEW [ IF EXISTS ] view_name; W przypadku braku perspektywy o podanej nazwie zgłoszony zostanie błąd, chyba że podana będzie opcja IF EXISTS - wtedy no-op. Baza danych Cassandra. Język CQL. 42/56 Funkcje CQL wspiera dwa rodzaje funkcji: funkcje skalarne - przyjmują określoną liczbę parametrów i zwracają wartość, funkcje agregacyjne - używane do agregowania wyników składających się z wielu wierszy zapytania SELECT. W obu przypadkach CQL zawiera zbiór gotowych funkcji jak i możliwość utworzenia nowych funkcji użytkownika. Funkcja jest definiowana przez nazwę: function_name ::= [ keyspace_name '.' ] name Używanie funkcji utworzonych przez użytkownika jest domyślnie wyłączone. Odpowiada za to opcja enable_user_defined_functions w pliku cassandra.yaml. Nawet włączone, funkcje użytkownika są uruchamiane w piaskownicy (ang. sandbox) tak, aby nie mogły uszkodzić danych. Baza danych Cassandra. Język CQL. 43/56 Funkcje skalarne Natywne funkcje skalarne: cast - pozwala przekształcać jedne natywne typy na inne, token - wyznacza token dla podanego klucza partycjonowania, uuid - bez parametrów, generuje losowe uuid typu 4 odpowiednie dla INSERT i UPDATE, funkcje timeuuid: now - generuje nowy, unikalny timeuuid, minTimeuuid - najmniejsze timeuuid mające określony punkt czasowy, maxTimeuuid - największe timeuuid mające określony punkt czasowy, funkcje konwersji czasu: toDate, toTimestamp, toUnixTimestamp, dateOf, unixTimestampOf funkcje konwersji danych typu blob: format funkcji typeAsBlob, gdzie type to dowolny typ danych (oprócz blob), np.: bigintAsBlob(3) zwraca 0x0000000000000003, odwrotnie, format funkcji blobAsType, gdzie type to dowolny typ, np.: blobAsBigint(0x0000000000000003) zwraca 3. Baza danych Cassandra. Język CQL. 44/56 Funkcje użytkownika Funkcje użytkownika: pozwalają na wykonanie kodu dostarczonego przez użytkownika, są w Cassandrze domyślnie wspierane dla języków Java i JavaScript, wsparcie dla innych języków (Python, Ruby i Scala) jest możliwe po dodaniu plików JAR, są częścią schematu Cassandry - są automatycznie rozsyłane do wszystkich węzłów klastra, można je przeładowywać, np.: CREATE FUNCTION przyklad ( arg int ) ...; CREATE FUNCTION przyklad ( arg text ) ...; Baza danych Cassandra. Język CQL. 45/56 Funkcje użytkownika create_function_statement ::= arguments_declaration ::= CREATE [ OR REPLACE ] FUNCTION [ IF NOT EXISTS] function_name '(' arguments_declaration ')' [ CALLED | RETURNS NULL ] ON NULL INPUT RETURNS cql_type LANGUAGE identifier AS string identifier cql_type ( ',' identifier cql_type )* Funkcje użytkownika: są podatne na problemy i błędy języka, w którym są napisane, implementacja powinna być odporna na wyjątki wystąpień wartości NULL, niepoprawnych argumentów i innych potencjalnych źródeł wyjątkow, wyjątek w trakcie działania funkcji przerywa wykonywania całego zapytania, można używać typów danych użytkownika zarówno w argumentach jak i zwracanej wartości, można ich używać w poleceniach SELECT, INSERT i UPDATE. Baza danych Cassandra. Język CQL. 46/56 Funkcje użytkownika - przykłady I CREATE FUNCTION przyklad1(arg text) RETURNS NULL ON NULL INPUT RETURNS double LANGUAGE javascript AS $$ arg.length; $$; CREATE FUNCTION przyklad2(arg text) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS $$ return arg.length(); $$; SELECT rezyser, przyklad1(rezyser) FROM filmy; rezyser | przyklad(rezyser) ------------------+----------------------Stanisław Bareja | 16 Akira Kurosawa | 14 Andrzej Wajda | 13 S. Bareja | 9 Robert Zemeckis | 15 Baza danych Cassandra. Język CQL. 47/56 Funkcje użytkownika - przykłady II CREATE FUNCTION razy_dwa ( arg int ) RETURNS NULL ON NULL INPUT RETURNS int LANGUAGE java AS $$ return 2*arg; $$; CREATE FUNCTION film_info(tytul text, rezyser text, glowny_aktor text) CALLED ON NULL INPUT RETURNS text LANGUAGE javascript AS $$ if(glowny_aktor==null) // albo if(!glowny_aktor) glowny_aktor = '--brak--'; tytul+' ('+rezyser+', '+glowny_aktor+')'; $$; SELECT film_info(tytul, rezyser, glowny_aktor) FROM filmy; mpk.film_info(tytul, rezyser, glowny_aktor) ---------------------------------------------Miś (Stanisław Bareja, Stanisław Tym) Siedmiu samurajów (Akira Kurosawa, --brak--) Pan Tadeusz (Andrzej Wajda, --brak--) Mis (S. Bareja, Stanisław Tym) Forrest Gump (Robert Zemeckis, Tom Hanks) Baza danych Cassandra. Język CQL. 48/56 Usuwanie funkcji użytkownika drop_function_statement ::= arguments_signature ::= DROP FUNCTION [ IF EXISTS ] function_name [ '(' arguments_signature ')' ] cql_type ( ',' cql_type )* Przykłady: DROP FUNCTION mojafunkcja; DROP FUNCTION lab11.film_info; DESC function przyklad; DROP FUNCTION przyklad (); DROP FUNCTION przyklad ( int ); DROP FUNCTION przyklad ( text ); Baza danych Cassandra. Język CQL. 49/56 Funkcje agregujące Funkcje agregujące: działają na zbiorze wierszy, przyjmują wartości z każdego wiersza i zwracają jedną wartość dla całego zbioru. Jeśli oprócz funkcji agregacji są wybierane jeszcze: normalne kolumny, funkcje skalarne, pola z typem użytkownika, writetime albo ttl to zwróconą wartością będzie pierwszy dopasowany wiersz. Baza danych Cassandra. Język CQL. 50/56 Natywne funkcje agregujące działają na zbiorach wierszy, otrzymują wartości z każdego wiersza i zwracają jedną wartość dla całego zbioru, Count - zlicza liczbę wierszy zwróconych przez zapytanie albo liczbę niepustych wartości danej kolumny, MIN i MAX zwracają najmniejszą i największą wartość zwróconą przez zapytanie z danej kolumny, MIN i MAX dla kolumn, dla których niem można porównywać, zwracają pierwszy i ostatni wiersz, SUM liczy sumę wartości w danej kolumnie ze zwróconych wierszy, AVG liczy średnią wartości danej kolumny ze zwróconych wierszy. Baza danych Cassandra. Język CQL. 51/56 Natywne funkcje agregujące - przykłady SELECT count(*) FROM filmy; // liczba wszystkich filmów, 8 wierszy SELECT count(1) FROM filmy; // j.w. SELECT count(cena) FROM filmy; // liczba niepustych wartości ceny, 7 wierszy SELECT min(produkcja) FROM filmy; // wartość kolumny pierwszego wiersza, Japonia SELECT max(produkcja) FROM filmy; // wartość kolumny ostatniego wiersza, USA SELECT min(cena) FROM filmy; SELECT max(cena) FROM filmy; // minimalna wartość ceny filmu // maksymalna wartość ceny filmu SELECT sum(cena) FROM filmy; // suma ceny wszystkich filmów SELECT avg(cena) FROM filmy; // średnia wartość ceny wszystkich filmów // średnia cena komedii polskich i amerykańskich SELECT avg(cena) as "Srednia" FROM filmy WHERE gatunek='komedia' AND produkcja IN ('Polska', 'USA'); Baza danych Cassandra. Język CQL. 52/56 Wsparcie dla formatu JSON Od Cassandry 2.2 dodano wsparcie dla formatu JSON w poleceniach SELECT i INSERT. Nie zmienia to samego API języka CQL, tylko je ubogaca ułatwiając pracę z dokumentami JSON. Kodowanie JSON w typach danych Cassandra: Baza danych Cassandra. Język CQL. 53/56 Funkcja fromJson() Funkcja fromJson(): może być używana podobnie jak INSERT JSON ale dla pojedynczej kolumny, można jej tylko używać w klauzuli VALUES polecenia INSERT albo jako wartość jednej z kolumn w poleceniach UPDATE, DELETE albo SELECT, nie można jej użyć w klauzuli selekcji polecenia SELECT. Przykłady: select * FROM filmy WHERE tytul='Miś' AND gatunek='komedia' AND produkcja='Polska'; select * FROM filmy WHERE tytul=fromJson('"Miś"') AND gatunek='komedia' AND produkcja='Polska'; // OK, normalne zapytanie select rezyser FROM filmy WHERE tytul=fromJson('"Miś"') AND gatunek='komedia' AND produkcja='Polska'; // Błąd, nie można używać w klauzuli selekcji select fromJson('rezyser') FROM filmy WHERE tytul=fromJson('"Miś"') AND gatunek='komedia' AND produkcja='Polska'; Baza danych Cassandra. Język CQL. 54/56 Funkcja toJson() Funkcja toJson(): używana tylko w klauzuli selekcji zapytania SELECT, używana tylko na pojedynczej kolumnie. Przykłady: select toJson(rezyser) FROM filmy2 WHERE tytul=fromJson('"Miś"') AND gatunek='komedia' AND produkcja='Polska'; select toJson(tytul) FROM filmy WHERE tytul='Ryś' AND gatunek='komedia' AND produkcja='Polska'; select toJson(aktorzy),toJson(tytul) FROM filmy WHERE tytul='Tato' AND gatunek='dramat' AND produkcja='Polska'; system.tojson(aktorzy) | system.tojson(tytul) ----------------------------------------------+---------------------{"6": "Bogusław Linda", "7": "Dorota Segda"} | "Tato" select aktorzy,tytul FROM filmy WHERE tytul='Tato' AND gatunek='dramat' AND produkcja='Polska'; aktorzy | tytul ------------------------------------------+------{6: 'Bogusław Linda', 7: 'Dorota Segda'} | Tato Baza danych Cassandra. Język CQL. 55/56 Źródła https://www.g2crowd.com/press-release/ best-nosql-databases-fall-2015/ https://en.wikipedia.org/wiki/Apache_Cassandra http://cassandra.apache.org/doc/latest/ https://docs.datastax.com/en/cql/3.1/cql/cql_intro_c.html Baza danych Cassandra. Język CQL. 56/56