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

PostgreSQL 12:Външни ключове и разделени таблици

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

Защо изтъквам това? Две причини:първо, когато разделените таблици бяха въведени за първи път в PostgreSQL 10, те изобщо не поддържаха външни ключове; не можете да създадете FK върху разделени таблици, нито да създадете FK, които препращат към разделена таблица. Второ, защото функцията за наследяване на таблици (от първите дни) също не поддържаше външни ключове. Всичко това означава, че за първи път в PostgreSQL е възможно да се поддържат големи обеми данни, като се поддържа референтна цялост. Сега, когато тази функция е завършена, някои нови случаи на употреба са отворени за PostgreSQL, които преди не са били.

Ето един доста тривиален пример.

CREATE TABLE items (
    item_id integer PRIMARY KEY,
    description text NOT NULL
) PARTITION BY hash (item_id);
CREATE TABLE items_0 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 0);
CREATE TABLE items_1 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 1);
CREATE TABLE items_2 PARTITION OF items FOR VALUES WITH (modulus 3, remainder 2);

CREATE TABLE warehouses (warehouse_id integer primary key, location text not null);

CREATE TABLE stock (
    item_id integer not null REFERENCES items,
    warehouse_id integer not null REFERENCES warehouses,
    amount int not null
) partition by hash (warehouse_id);
CREATE TABLE stock_0 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 0);
CREATE TABLE stock_1 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 1);
CREATE TABLE stock_2 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 2);
CREATE TABLE stock_3 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 3);
CREATE TABLE stock_4 PARTITION OF stock FOR VALUES WITH (modulus 5, remainder 4);

Тук можете да видите, че има два външни ключа. Единият сочи към обикновена (неразделена) таблица складове , другият сочи към елементи на разделена таблица . Забелязахте ли, че всеки външен ключ се декларира само веднъж?

Има две основни операции, които искате да предостави външният ключ. Първо, ако вмъкнете ред в сток (препращането таблица), която няма съответен ред в items или складове (посоченият таблица), трябва да се повдигне грешка. Второ, ако изтриете ред в някоя от посочените таблици и има съвпадащи редове в сток , тази операция също трябва да бъде отхвърлена.

И двете се проверяват лесно:

INSERT INTO stock values (1, 1, 10);
ERROR:  insert or update on table "stock_0" violates foreign key constraint "stock_item_id_fkey"
DETAIL:  Key (item_id)=(1) is not present in table "items".

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

INSERT INTO items VALUES (1, 'item 1');
INSERT INTO warehouses VALUES (1, 'The moon');
INSERT INTO stock VALUES (1, 1, 10);

DELETE FROM warehouses;
ERROR:  update or delete on table "warehouses" violates foreign key constraint "stock_warehouse_id_fkey" on table "stock"
DETAIL:  Key (warehouse_id)=(1) is still referenced from table "stock".

DELETE FROM items;
ERROR:  update or delete on table "items_2" violates foreign key constraint "stock_item_id_fkey3" on table "stock"
DETAIL:  Key (item_id)=(1) is still referenced from table "stock".

(Разбира се, АКТУАЛИЗИРАНЕ операцията за предишната операция е същата като INSERT , а за последната операция е същата като DELETE — което означава, че както оригиналният, така и модифицираният кортеж трябва да бъдат проверени, ако UPDATE променя колоните, включени във външния ключ.)

Ако тези примери изглеждат скучни на опитни потребители, това е, защото тези неща работят точно по същия начин за обикновени (неразделени) таблици от незапомнени времена.

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

CREATE INDEX ON stock (item_id);
CREATE INDEX ON stock (warehouse_id);

В тази публикация показах основите на външните ключове и как те могат да се използват в разделени таблици, точно както могат в обикновени таблици. В следваща публикация ще разгледам няколко допълнителни функции от тях. Кажете ми в коментар, ако ви харесва това подобрение на PostgreSQL 12!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Настройка и поддръжка на PostgreSQL репликация с помощта на Ansible

  2. Управлявайте обединяването на връзки в уеб приложение с множество наематели с Spring, Hibernate и C3P0

  3. Изпълнявайте отложен тригер само веднъж на ред в PostgreSQL

  4. Вмъквайте данни в 3 таблици наведнъж с помощта на Postgres

  5. Върнете само числовите стойности от колона на PostgreSQL база данни