PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Споделяне на вашите данни с PostgreSQL 11

Версия 10 на PostgreSQL добави декларативното разделяне на таблица функция. Във версия 11 (понастоящем в бета) можете да комбинирате това с чужди обвивки на данни , осигуряващ механизъм за вътрешно разделяне на вашите таблици в множество сървъри PostgreSQL.

Декларативно разделяне

Помислете за таблица, която съхранява дневните минимални и максимални температури на градовете за всеки ден:

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

Спецификацията на таблицата е умишлено лишена от ограничения за колони и първичен ключ, за да поддържаме нещата прости – ще ги добавим по-късно.

Много често се установява, че в много приложения най-новите данни са по-често достъпни. Помислете за текущата финансова година, този месец, последния час и така нататък. Тъй като нашата таблица с „температури“ расте, има смисъл да преместим старите данни в друга таблица със същата структура. Можем например да направим това:

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;

за да преместите всички записи от 2017 г. в друга таблица. Това оставя основната таблица с „температури“ по-малка и по-бърза, за да може приложението да работи с нея. Като бонус, ако сега трябва да изтриете стари данни, можете да го направите, без да забавяте вмъкването на входящи данни в основната/текущата таблица, тъй като старите данни се съхраняват в друга таблица.

Но наличието на множество различни таблици означава, че кодът на приложението сега трябва да се промени. Ако трябва да получи достъп до по-стари данни, да речем получаване на годишните мин. и максимални температури на даден град, сега трябва да разбере какви таблици присъстват в схемата, да потърси всяка от тях и да комбинира резултатите от всяка таблица. Можем ли да направим това без промяна на кода на приложението?

Разделянето прави това възможно. В PostgreSQL 10 можете да създадете таблица с „температури“ по следния начин:

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

Това прави „температурите“ главна таблица на дяловете и казва на PostgreSQL, че ще създадем множество разделени таблици, съхраняващи неприпокриващи се данни, всяка с различен набор от стойности „at“. Самата главна таблица не съдържа никакви данни, но може да бъде запитана и вмъкната от приложението от приложението – което не знае за дъщерните дялове, съдържащи действителните данни.

А ето и нашите дялове:

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

Вече имаме две таблици, едната, която ще съхранява данни за 2017 г., а другата за 2018 г. Имайте предвид, че стойността „от“ включва, но стойността „до“ не е. Нека я изпробваме:

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)

„Приложението“ може да вмъква и избира от основната таблица, но PostgreSQL насочва действителните данни в съответните дъщерни таблици. (О и BTW, тези температури са реални!)

Индекси и ограничения

Индексите и ограниченията за таблици и колони всъщност са дефинирани на ниво таблица на дялове, тъй като там се намират действителните данни. Можете да зададете тези по време на създаването на таблицата на дяловете:

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 ви позволява да дефинирате индекси на родителската таблица и ще създава индекси на съществуващи и бъдещи таблици на дялове. Прочетете повече тук.

Обвивка на чужди данни

Функционалността за обвиване на чужди данни съществува в Postgres от известно време. PostgreSQL ви позволява да осъществявате достъп до данни, съхранявани в други сървъри и системи, използвайки този механизъм. Това, което ни интересува, е „postgres_fdw“, което ще ни позволи достъп до един Postgres сървър от друг.

“postgres_fdw” е разширение, присъстващо в стандартната дистрибуция, което може да се инсталира с обикновената команда CREATE EXTENSION:

CREATE EXTENSION postgres_fdw;

Да предположим, че имате друг PostgreSQL сървър „box2“ с база данни, наречена „box2db“. Можете да създадете „чужд сървър“ за това:

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

Нека също така съпоставим нашия потребител „alice“ (потребителят, от който сте влезли) към box2 user „box2alice“. Това позволява на “alice” да бъде “box2alice” при достъп до отдалечени таблици:

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

Вече имате достъп до таблици (също изгледи, matviews и т.н.) на box2. Първо създайте таблица на box2 и след това „чужда таблица“ на вашия сървър. Външната таблица не съдържа никакви реални данни, но служи като прокси за достъп до таблицата box2.

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

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

Външната таблица във вашия сървър може да участва в транзакции по същия начин като нормалните таблици. Приложенията не трябва да знаят, че таблиците, с които взаимодейства, са местни или чужди – въпреки че ако приложението ви изпълнява SELECT, който може да издърпа много редове от чужда таблица, това може да забави нещата. В Postgres 10 бяха направени подобрения за натискане на съединения надолу и агрегира към отдалечения сървър.

Комбиниране на разделяне и FDW

И сега за забавната част:настройване на дялове на отдалечени сървъри.

Първо, нека създадем таблицата на физическите дялове на box2:

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

И след това създайте дяла на вашия сървър, като чужда таблица:

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

Вече можете да вмъквате и да правите заявки от собствения си сървър:

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)

Ето го! Възможността за вмъкване на редове в отдалечен дял е нова версия 11. С тази функция вече можете да разпределите данните си логически (раздели) и физически (FDW).

Управление на данни

Команди като VACUUM и ANALYZE работят както бихте очаквали с главните таблици на дялове – всички локални дъщерни таблици са обект на VACUUM и ANALYZE. Дяловете могат да се отделят, данните се манипулират без ограничението на дяла и след това се прикачват отново. Самите дъщерни таблици на дялове могат да бъдат разделени.

Преместването на данни („преразпределяне“) може да се извърши с обикновени SQL оператори (вмъкване, изтриване, копиране и т.н.). Могат да се създават локални индекси и тригери за дял.

Добавянето на излишък към вашите фрагменти се постига лесно с логическо или поточно репликация.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Бройте дните между 2 дати в JPA

  2. Вземете отделната сума от колона на присъединена таблица

  3. Ако PostgreSQL count(*) винаги е бавен, как да се пагинират сложни заявки?

  4. Внедряване на настройка с множество центрове за данни за PostgreSQL – част първа

  5. Защо е най-добре да съхранявате телефонен номер като низ спрямо цяло число?