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

Podobne dokumenty