sql >> Databáze >  >> RDS >> PostgreSQL

Sdílení dat pomocí PostgreSQL 11

Verze 10 PostgreSQL přidala deklarativní rozdělení tabulek feature.Ve verzi 11 (aktuálně ve verzi beta) to můžete zkombinovat se zahraničními datawrappery , poskytující mechanismus pro nativní sdílení vašich tabulek na více serverech PostgreSQL.

Deklarativní rozdělení

Zvažte tabulku, která ukládá denní minimální a maximální teploty ve městech pro každý den:

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

Specifikace tabulky záměrně postrádá omezení sloupců a primární klíč, aby byly věci jednoduché – přidáme je později.

Je velmi běžné zjistit, že v mnoha aplikacích se častěji přistupuje k nejnovějším datům. Myslete na aktuální finanční rok, tento měsíc, poslední hodinu a tak dále. Jak naše tabulka „teplot“ roste, dává smysl přesunout stará data do jiné tabulky se stejnou strukturou. Můžeme například udělat toto:

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;

přesunout všechny záznamy z roku 2017 do jiné tabulky. Tím zůstane hlavní tabulka „teplot“ menší a rychlejší, aby aplikace mohla pracovat. Jako bonus, pokud nyní potřebujete smazat stará data, můžete tak učinit bez zpomalení vkládání příchozích dat do hlavní/aktuální tabulky, protože stará data žijí v jiné tabulce.

Ale mít více různých tabulek znamená, že kód aplikace se nyní musí změnit. Pokud má získat přístup ke starším datům, řekněme získat roční minimální a maximální teploty města, musí nyní zjistit, jaké tabulky jsou ve schématu, dotazovat se na každou z nich a zkombinovat výsledky z každé tabulky. Můžeme to udělat bez změny kódu aplikace?

Dělení to umožňuje. V PostgreSQL 10 můžete vytvořit tabulku „teplot“ takto:

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

To dělá z „teplot“ hlavní tabulku oddílů a říká PostgreSQL, že vytvoříme více rozdělených tabulek s nepřekrývajícími se daty, každou s jinou sadou hodnot „at“. Samotná hlavní tabulka neobsahuje žádná data, ale lze se na ni dotazovat a vkládat do aplikace – což nezná podřízené oddíly obsahující aktuální data.

A zde jsou naše oddíly:

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');

Nyní máme dvě tabulky, jednu, která bude ukládat data za rok 2017 a další za rok 2018. Všimněte si, že hodnota „od“ je včetně, ale hodnota „do“ nikoli. Pojďme si to vyzkoušet:

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)

„Aplikace“ je schopna vkládat a vybírat z hlavní tabulky, ale PostgreSQL směruje aktuální data do příslušných podřízených tabulek. (Oh andBTW, ty teploty jsou skutečné!)

Indexy a omezení

Indexy a omezení tabulek a sloupců jsou ve skutečnosti definovány na úrovni tabulky rozdělení, protože tam jsou skutečná data. Při vytváření tabulky oddílů můžete nastavit:

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 vám umožňuje definovat indexy na nadřazené tabulce a vytvoří indexy na existujících a budoucích tabulkách oddílů. Přečtěte si více zde.

Foreign Data Wrapper

Funkce zalamování cizích dat v Postgresu již nějakou dobu existuje. PostgreSQL vám umožňuje přistupovat k datům uloženým na jiných serverech a systémech pomocí tohoto mechanismu. To, co nás zajímá, je „postgres_fdw“, což je to, co nám umožní přístup k jednomu serveru Postgres z jiného.

„postgres_fdw“ je rozšíření přítomné ve standardní distribuci, které lze nainstalovat pomocí běžného příkazu CREATE EXTENSION:

CREATE EXTENSION postgres_fdw;

Předpokládejme, že máte další PostgreSQL server „box2“ s databází nazvanou „box2db“. Za tímto účelem můžete vytvořit „zahraniční server“:

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

Pojďme také namapovat našeho uživatele „alice“ (uživatel, pod kterým jste přihlášeni) na uživatele box2 „box2alice“. To umožňuje, aby „alice“ byla „box2alice“ při přístupu ke vzdáleným tabulkám:

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

Nyní máte přístup k tabulkám (také pohledům, matviews atd.) na box2. Nejprve vytvořte tabulku na box2 a poté „cizí stůl“ na vašem serveru. Cizí tabulka neuchovává žádná aktuální data, ale slouží jako proxy pro přístup k tableon box2.

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

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

Cizí tabulka na vašem serveru se může účastnit transakcí stejně jako normální tabulky. Aplikace nemusí vědět, že tabulky, se kterými interagují, jsou místní nebo cizí – i když pokud vaše aplikace spouští SELECT, který může stáhnout spoustu řádků z cizí tabulky, může to zpomalit. V Postgres 10 byla provedena vylepšení pro potlačení spojení a agregovat na vzdálený server.

Kombinace dělení a FDW

A teď ta zábavná část:nastavení oddílů na vzdálených serverech.

Nejprve vytvořte tabulku fyzických oddílů na box2:

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

A poté vytvořte oddíl na vašem serveru jako cizí tabulku:

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

Nyní můžete vkládat a dotazovat se ze svého vlastního serveru:

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)

Tady to máš! Možnost vkládat řádky do vzdáleného oddílu je novinkou ve verzi 11. S touto funkcí nyní můžete mít svá data logicky (oddíly) a fyzicky (FDW) shardovat.

Správa dat

Příkazy jako VACUUM a ANALYZE fungují tak, jak byste očekávali s hlavními tabulkami oddílů – všechny místní podřízené tabulky podléhají funkcím VACUUM a ANALYZE. Oddíly lze odpojit, s daty lze manipulovat bez omezení oddílu a poté je znovu připojit. Samotné podřízené tabulky oddílů lze rozdělit.

Přesouvání dat (“reharding”) lze provádět pomocí běžných příkazů SQL (vložení, smazání, kopírování atd.). Lze vytvořit místní indexy a spouštěče.

Přidání redundance do vašich fragmentů lze snadno dosáhnout pomocí logické nebo streamingové replikace.


  1. Porozumění tomu, jak Android.com ukládá data v SQL Database Tutorial

  2. Je možné odkazovat na názvy sloupců pomocí vazebných proměnných v Oracle?

  3. Povolit uživatelům přístup pouze k určitým tabulkám v mém poskytovateli obsahu

  4. Jak rozdělit řetězec a vložit hodnoty do tabulky v SQL Server