sql >> Databasteknik >  >> RDS >> PostgreSQL

Dela dina data med PostgreSQL 11

Version 10 av PostgreSQL lade till deklarativ tabellpartitionering feature.I version 11 (för närvarande i betaversion) kan du kombinera detta med utländska datawrappers , tillhandahåller en mekanism för att söndra dina tabeller över flera PostgreSQL-servrar.

Deklarativ partitionering

Överväg en tabell som lagrar de dagliga lägsta och högsta temperaturerna för städer för varje dag:

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

Tabellspecifikationen saknar avsiktligt kolumnbegränsningar och primärnyckel för att göra saker enkelt – vi lägger till dessa senare.

Det är mycket vanligt att upptäcka att i många applikationer är den senaste informationen mer frekvent åtkomlig. Tänk på innevarande räkenskapsår, denna månad, sista timmen och så vidare. När vår "temperatur"-tabell växer, är det vettigt att flytta ut den gamla data till en annan tabell, med samma struktur. Vi kan till exempel göra detta:

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;

för att flytta alla poster från år 2017 till en annan tabell. Detta gör att huvudtabellen "temperaturer" blir mindre och snabbare för applikationen att arbeta med. Som en bonus, om du nu behöver radera gamla data, kan du göra det utan att sakta ner infogning av inkommande data i huvud-/aktuella tabellen eftersom de gamla data lever i en annan tabell.

Men att ha flera, distinkta tabeller innebär att applikationskoden nu måste ändras. Om den måste komma åt äldre data, t.ex. att få de årliga min- och maxtemperaturerna för en stad, måste den nu ta reda på vilka tabeller som finns i schemat, fråga var och en av dem och kombinera resultaten från varje tabell. Kan vi göra detta utan att ändra applikationskoden?

Partitionering gör detta möjligt. I PostgreSQL 10 kan du skapa tabellen "temperaturer" så här:

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

Detta gör "temperaturer" till en partitionsmastertabell och berättar för PostgreSQL att vi kommer att skapa flera partitionerade tabeller som lagrar icke-överlappande data, var och en med olika uppsättningar "at"-värden. Själva huvudtabellen innehåller inga data, men kan efterfrågas från och infogas av applikationen – som är okunnig om de underordnade partitionerna som innehåller den faktiska data.

Och här är våra partitioner:

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

Vi har nu två tabeller, en som kommer att lagra data för 2017 och en annan för 2018. Observera att "från"-värdet är inklusive, men att "till"-värdet inte är det. Låt oss prova det:

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)

"Applikationen" kan infoga i och välja från huvudtabellen, men PostgreSQL dirigerar den faktiska datan till lämpliga underordnade tabeller. (Åh och förresten, de temperaturerna är riktiga!)

Index och begränsningar

Index och tabell- och kolumnbegränsningar definieras faktiskt på partitionstabellnivå, eftersom det är där den faktiska informationen finns. Du kan ställa in dessa när partitionstabellen skapas:

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 låter dig definiera index på den överordnade tabellen, och kommer att skapa index på befintliga och framtida partitionstabeller. Läs mer här.

Utländsk dataomslag

Den främmande datainpackningsfunktionen har funnits i Postgres under en tid. PostgreSQL låter dig komma åt data som lagras i andra servrar och system med hjälp av denna mekanism. Det vi är intresserade av är "postgres_fdw", vilket är det som gör att vi kan komma åt en Postgres-server från en annan.

"postgres_fdw" är ett tillägg som finns i standarddistributionen, som kan installeras med det vanliga CREATE EXTENSION-kommandot:

CREATE EXTENSION postgres_fdw;

Låt oss anta att du har en annan PostgreSQL-server "box2" med en databas som heter "box2db". Du kan skapa en "utländsk server" för detta:

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

Låt oss också mappa vår användare "alice" (användaren du är inloggad som) till box2 användare "box2alice". Detta tillåter "alice" att vara "box2alice" när du kommer åt fjärrtabeller:

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

Du kan nu komma åt tabeller (även vyer, matvyer etc) på box2. Skapa först en tabell på box2 och sedan ett "utländskt bord" på din server. De främmande tabellerna innehåller inga faktiska data, men fungerar som en proxy för åtkomst till tabellbox2.

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

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

Den främmande tabellen på din server kan delta i transaktioner på samma sätt som vanliga tabeller. Applikationer behöver inte veta att tabellerna den interagerar med är lokala eller utländska – även om din app kör en SELECT som kan dra in många rader från en främmande tabell kan det sakta ner saker och ting. I Postgres 10 gjordes förbättringar för att trycka ned sammanfogningar och samlas till fjärrservern.

Kombinera partitionering och FDW

Och nu till det roliga:att sätta upp partitioner på fjärrservrar.

Låt oss först skapa den fysiska partitionstabellen på box2:

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

Och skapa sedan partitionen på din server, som en främmande tabell:

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

Du kan nu infoga och fråga från din egen server:

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)

Där har du det! Att kunna infoga rader i en fjärrpartition är nytt i version 11. Med den här funktionen kan du nu dela dina data logiskt (partitioner) och fysiskt (FDW).

Datahantering

Kommandon som VACUUM och ANALYSE fungerar som du kan förvänta dig med partitionsmastertabeller – alla lokala underordnade tabeller är föremål för VACUUM och ANALYSE. Partitioner kan kopplas bort, det är data som manipuleras utan partitionsbegränsningen och sedan kopplas till igen. Själva partitionsunderordnade tabeller kan partitioneras.

Att flytta runt data (“omskärning”) kan göras med vanliga SQL-satser (infoga, ta bort, kopiera etc.). Partitionslokala index och triggers kan skapas.

Att lägga till redundans till dina skärvor uppnås enkelt med logisk eller streamingreplikering.


  1. Finns det någon skillnad mellan SQL Server Express (2012) och LocalDB?

  2. SQL Server som kör övervakning av frågor

  3. SQL Server 2016:Skapa en tabell från ett SQL-skript

  4. Ändra startnummer för automatisk ökning?