PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Dzielenie danych z PostgreSQL 11

Wersja 10 PostgreSQL dodała deklaratywne partycjonowanie tabeli funkcja.W wersji 11 (obecnie w wersji beta) możesz połączyć to z obcymi datawrapperami , zapewniając mechanizm do natywnego dzielenia tabel na wiele serwerów PostgreSQL.

Partycjonowanie deklaratywne

Rozważ tabelę, która przechowuje dzienne minimalne i maksymalne temperatury w miastach na każdy dzień:

CREATE TABLE temperatures (
    at      date,
    city    text,
    mintemp integer,
    maxtemp integer
);

Specyfikacja tabeli jest celowo pozbawiona ograniczeń dotyczących kolumn i klucza podstawowego, aby wszystko było proste – dodamy je później.

Bardzo często zdarza się, że w wielu aplikacjach częściej uzyskuje się dostęp do najnowszych danych. Pomyśl o bieżącym roku finansowym, bieżącym miesiącu, ostatniej godzinie i tak dalej. Gdy nasza tabela „temperatur” rośnie, sensowne jest przeniesienie starych danych do innej tabeli o tej samej strukturze. Możemy na przykład zrobić to:

CREATE TABLE temperatures_2017 (LIKE temperatures);
INSERT INTO temperatures_2017 SELECT * FROM temperatures WHERE
	extract(year from at) = 2017;
DELETE FROM temperatures WHERE extract(year from at) = 2017;

przenieść wszystkie wpisy z roku 2017 do innej tabeli. Powoduje to, że główna tabela „temperatur” jest mniejsza i szybsza, aby aplikacja mogła działać. Jako bonus, jeśli teraz musisz usunąć stare dane, możesz to zrobić bez spowalniania wstawiania danych przychodzących do głównej/bieżącej tabeli, ponieważ stare dane są aktywne w innym stole.

Jednak posiadanie wielu odrębnych tabel oznacza, że ​​kod aplikacji musi się teraz zmienić. Jeśli musi uzyskać dostęp do starszych danych, na przykład uzyskać roczne minimalne i maksymalne temperatury miasta, musi teraz dowiedzieć się, jakie tabele są obecne w schemacie, wykonać zapytanie do każdej z nich i połączyć wyniki z każdej tabeli. Czy możemy to zrobić bez zmiany kodu aplikacji?

Umożliwia to partycjonowanie. W PostgreSQL 10 możesz utworzyć tabelę „temperatur” w następujący sposób:

CREATE TABLE temperatures (
    at      date,
    city    text,
    mintemp integer,
    maxtemp integer
)
PARTITION BY RANGE (at);

To sprawia, że ​​„temperatury” są główną tabelą partycji i mówi PostgreSQL, że zamierzamy utworzyć wiele podzielonych na partycje tabel przechowujących nienakładające się dane, z których każda ma inny zestaw wartości „at”. Sama tabela główna nie przechowuje żadnych danych, ale może być odpytywana przez aplikację i do niej wstawiana – co nie uwzględnia partycji podrzędnych przechowujących rzeczywiste dane.

A oto nasze partycje:

CREATE TABLE temperatures_2017
    PARTITION OF temperatures
    FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');

CREATE TABLE temperatures_2018
    PARTITION OF temperatures
    FOR VALUES FROM ('2018-01-01') TO ('2019-01-01');

Mamy teraz dwie tabele, jedną, która będzie przechowywać dane za rok 2017, a drugą za rok 2018.Pamiętaj, że wartość „od” jest inkluzywna, ale wartość „do” już nie.Wypróbujmy to:

temp=# INSERT INTO temperatures (at, city, mintemp, maxtemp)
temp-#        VALUES ('2018-08-03', 'London', 63, 90);
INSERT 0 1
temp=# INSERT INTO temperatures (at, city, mintemp, maxtemp)
temp-#        VALUES ('2017-08-03', 'London', 59, 70);
INSERT 0 1
temp=# SELECT * FROM temperatures;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2017-08-03 | London |      59 |      70
 2018-08-03 | London |      63 |      90
(2 rows)

temp=# SELECT * FROM temperatures_2017;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2017-08-03 | London |      59 |      70
(1 row)

temp=# SELECT * FROM temperatures_2018;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2018-08-03 | London |      63 |      90
(1 row)

„Aplikacja” może wstawiać i wybierać z głównej tabeli, ale PostgreSQL kieruje rzeczywiste dane do odpowiednich tabel podrzędnych. (Och i przy okazji, te temperatury są prawdziwe!)

Indeksy i ograniczenia

Indeksy oraz ograniczenia tabeli i kolumny są w rzeczywistości definiowane na poziomie partycji, ponieważ tam znajdują się rzeczywiste dane. Możesz ustawić te podczas tworzenia tablicy partycji:

CREATE TABLE temperatures_2017
    PARTITION OF temperatures (
        mintemp NOT NULL,
        maxtemp NOT NULL,
        CHECK (mintemp <= maxtemp),
        PRIMARY KEY (at, city)
    )
    FOR VALUES FROM ('2017-01-01') TO ('2018-01-01');

PostgreSQL 11 pozwala zdefiniować indeksy w tabeli nadrzędnej i utworzy indeksy w istniejących i przyszłych tabelach partycji. Przeczytaj więcej tutaj.

Opakowanie danych zagranicznych

Funkcjonalność opakowania danych obcych istnieje w Postgresie od jakiegoś czasu. Dzięki temu mechanizmowi PostgreSQL umożliwia dostęp do danych przechowywanych na innych serwerach i systemach. Interesuje nas „postgres_fdw”, co pozwoli nam uzyskać dostęp do jednego serwera Postgres z innego.

„postgres_fdw” to rozszerzenie obecne w standardowej dystrybucji, które można zainstalować za pomocą zwykłego polecenia CREATE EXTENSION:

CREATE EXTENSION postgres_fdw;

Załóżmy, że masz inny serwer PostgreSQL „box2” z bazą danych o nazwie „box2db”. W tym celu możesz utworzyć „obcy serwer”:

CREATE SERVER box2 FOREIGN DATA WRAPPER postgres_fdw
    OPTIONS (host 'box2', dbname 'box2db');

Zmapujmy również naszego użytkownika „alice” (użytkownika, jako którego jesteś zalogowany) na użytkownika box2 „box2alice”. Dzięki temu „alice” może być „box2alice” podczas uzyskiwania dostępu do zdalnych tabel:

CREATE USER MAPPING FOR alice SERVER box2
    OPTIONS (user 'box2alice');

Możesz teraz uzyskać dostęp do tabel (także widoków, widoków mat itp.) na box2. Najpierw utwórz tabelę na polu 2, a następnie „obcą tabelę” na swoim serwerze. Obca tabela nie przechowuje żadnych rzeczywistych danych, ale służy jako proxy dostępu do tabeli na polu2.

-- on box2
CREATE TABLE foo (a int);

-- on your server
IMPORT FOREIGN SCHEMA public LIMIT TO (foo)
    FROM SERVER box2 INTO public;

Stół obcy na twoim serwerze może uczestniczyć w transakcjach w taki sam sposób, jak zwykłe stoły. Aplikacje nie muszą wiedzieć, że tabele, z którymi wchodzi w interakcję, są lokalne czy obce — chociaż jeśli Twoja aplikacja uruchamia polecenie SELECT, które może pobierać wiele wierszy z obcej tabeli, może to spowolnić działanie. i agreguje do zdalnego serwera.

Łączenie partycjonowania i FDW

A teraz zabawna część:konfigurowanie partycji na zdalnych serwerach.

Najpierw utwórzmy tablicę partycji fizycznych na polu 2:

-- on box2
CREATE TABLE temperatures_2016 (
    at      date,
    city    text,
    mintemp integer,
    maxtemp integer
);

A następnie utwórz partycję na swoim serwerze jako obcą tabelę:

CREATE FOREIGN TABLE temperatures_2016
    PARTITION OF temperatures
    FOR VALUES FROM ('2016-01-01') TO ('2017-01-01')
    SERVER box2;

Możesz teraz wstawiać i wysyłać zapytania z własnego serwera:

temp=# INSERT INTO temperatures (at, city, mintemp, maxtemp)
temp-#     VALUES ('2016-08-03', 'London', 63, 73);
INSERT 0 1
temp=# SELECT * FROM temperatures ORDER BY at;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2016-08-03 | London |      63 |      73
 2017-08-03 | London |      59 |      70
 2018-08-03 | London |      63 |      90
(3 rows)

temp=# SELECT * FROM temperatures_2016;
     at     |  city  | mintemp | maxtemp
------------+--------+---------+---------
 2016-08-03 | London |      63 |      73
(1 row)

Masz to! Możliwość wstawiania wierszy do zdalnej partycji to nowość w wersji 11. Dzięki tej funkcji możesz teraz logicznie (partycje) i fizycznie (FDW) podzielić dane na części.

Zarządzanie danymi

Polecenia takie jak VACUUM i ANALYZE działają zgodnie z oczekiwaniami z tabelami głównymi partycji — wszystkie lokalne tabele podrzędne podlegają VACUUM i ANALYZE. Partycje można odłączyć, ich danymi można manipulować bez ograniczenia partycji, a następnie ponownie dołączyć. Same tabele podrzędne partycjonowania mogą być partycjonowane.

Przenoszenie danych („resharding”) można wykonać za pomocą zwykłych instrukcji SQL (wstaw, usuń, kopiuj itp.). Można tworzyć lokalne indeksy i wyzwalacze partycji.

Dodanie nadmiarowości do shardów można łatwo osiągnąć dzięki replikacji logicznej lub strumieniowej.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Zwiększanie wydajności PostgreSQL dzięki HAProxy

  2. Jak korzystać ze schematów w Django?

  3. Przygotowane oświadczenie na temat Postgresql w Rails

  4. Konwertuj zbiór wyników z tablicy SQL na tablicę ciągów

  5. czy powinienem aktywować łączenie wyciągów c3p0?