PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

PostgreSQL 12:Kunci Asing dan Tabel yang Dipartisi

Sekarang setelah PostgreSQL 12 keluar, kami menganggap kunci asing sepenuhnya kompatibel dengan tabel yang dipartisi. Anda dapat memiliki tabel yang dipartisi di kedua sisi batasan kunci asing, dan semuanya akan berfungsi dengan benar.

Mengapa saya menunjukkan hal ini? Dua alasan:pertama, ketika tabel yang dipartisi pertama kali diperkenalkan di PostgreSQL 10, tabel tersebut tidak mendukung kunci asing sama sekali; Anda tidak dapat membuat FK pada tabel yang dipartisi, atau membuat FK yang mereferensikan tabel yang dipartisi. Kedua, karena fitur pewarisan tabel (hari-hari awal) juga tidak terlalu mendukung kunci asing. Semua ini berarti bahwa untuk pertama kalinya PostgreSQL dapat mempertahankan volume data yang besar sambil mempertahankan integritas referensial. Sekarang setelah fitur ini selesai, beberapa kasus penggunaan baru terbuka untuk PostgreSQL yang sebelumnya tidak.

Ini contoh yang cukup sepele.

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

Anda dapat melihat ada dua kunci asing di sini. Satu menunjuk ke tabel biasa (tidak dipartisi) gudang , poin lainnya ke tabel yang dipartisi item . Apakah Anda memperhatikan bahwa setiap kunci asing hanya dideklarasikan satu kali?

Ada dua operasi dasar yang Anda inginkan untuk disediakan oleh kunci asing. Pertama, jika Anda memasukkan baris di stok (referensi tabel) yang tidak memiliki baris yang sesuai di item atau gudang (direferensikan tabel), kesalahan harus dimunculkan. Kedua, jika Anda menghapus satu baris di salah satu tabel yang direferensikan dan ada baris yang cocok di stok , operasi itu juga harus ditolak.

Keduanya mudah diverifikasi:

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".

Bagus. Kemudian Anda dapat menyisipkan baris yang cocok di tabel referensi dan baris referensi. Setelah itu, penghapusan di salah satu tabel yang direferensikan akan gagal, seperti yang diharapkan.

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".

(Tentu saja, sebuah UPDATE operasi untuk operasi sebelumnya sama dengan INSERT , dan untuk operasi terakhir sama dengan DELETE — artinya baik tupel asli maupun tupel yang dimodifikasi harus diperiksa, jika UPDATE memodifikasi kolom yang terlibat dalam kunci asing.)

Jika contoh-contoh ini tampak lemah bagi pengguna berpengalaman, itu karena hal-hal ini bekerja persis sama untuk tabel biasa (tidak dipartisi) sejak dahulu kala.

Dalam penggunaan nyata, Anda memerlukan indeks di kolom referensi di saham tabel, jika Anda pernah memodifikasi tabel yang direferensikan. Ini karena server perlu menemukan baris referensi tersebut untuk mengetahui kesalahan atau semacamnya. Anda dapat melakukannya dengan tabel referensi yang dipartisi dengan cukup mudah:

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

Dalam posting ini saya telah menunjukkan dasar-dasar kunci asing, dan bagaimana mereka dapat digunakan pada tabel yang dipartisi seperti halnya pada tabel biasa. Dalam posting berikutnya saya akan membahas beberapa fitur tambahan tersebut. Beri tahu saya di komentar jika Anda menyukai peningkatan PostgreSQL 12 ini!


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara menghubungkan Postgres ke server localhost menggunakan pgAdmin di Ubuntu?

  2. postgres kueri dinamis

  3. Bagaimana kata kunci IMMUTABLE, STABLE, dan VOLATILE memengaruhi perilaku fungsi?

  4. Bagaimana saya bisa menggabungkan kolom dari dua tabel menjadi satu output?

  5. kolom postgres X tidak ada