Tetapkan primary key (PK) pada tabel Anda untuk memastikan keunikan setiap record, menjaga konsistensi data, dan menyederhanakan manajemen data. Di Hologres, primary key memiliki atribut yang sama seperti pada database tradisional, berfungsi sebagai pengidentifikasi unik untuk record dalam suatu tabel. Kolom yang ditetapkan sebagai primary key harus bernilai unik dan tidak null. Anda juga dapat menetapkan beberapa kolom sebagai composite primary key. Topik ini menjelaskan cara menetapkan primary key untuk tabel di Hologres.
Pendahuluan
Di Hologres, sistem secara otomatis memelihara file indeks primary key di lapisan penyimpanan dasar. File ini menggunakan struktur row store untuk menyediakan layanan key-value (KV) berkecepatan tinggi. Kunci dalam file indeks tersebut adalah primary key (PK) tabel, sedangkan nilainya terdiri atas Row Identifier (RID)—sebelumnya disebut `unique_id`—dan Clustering Key. RID dihasilkan secara otomatis dan meningkat secara monoton pada setiap operasi UPSERT. File indeks primary key memungkinkan deteksi konflik primary key yang efisien serta membantu menemukan file data. Jika suatu tabel memiliki PK, Anda dapat dengan cepat menemukan RID dan Clustering Key dalam file indeks tersebut, lalu menggunakan keduanya untuk mengakses file data.
Menetapkan primary key di Hologres membantu memenuhi berbagai kebutuhan dalam skenario gudang data real-time:
Mendukung operasi UPSERT atau DELETE berkinerja tinggi.
Selain mendukung fitur penulisan append-only berkinerja tinggi dari database tradisional, Hologres menggunakan primary key untuk melakukan pembaruan berkinerja tinggi baik untuk seluruh baris maupun kolom tertentu. Saat melakukan pembaruan tulis, sistem memperbarui record berdasarkan primary key tanpa melakukan pemindaian tabel penuh. Proses ini mencapai operasi UPSERT berkinerja tinggi sekaligus menjamin keunikan data.
Mendukung kueri berbasis primary key dengan QPS tinggi.
Seperti dijelaskan dalam Format penyimpanan tabel: Berorientasi kolom, berorientasi baris, dan hibrida baris-kolom, jika suatu tabel memiliki PK, Anda dapat dengan cepat mengambil seluruh baris berdasarkan primary key tersebut. Hal ini meningkatkan performa kueri, terutama pada tabel berorientasi baris di mana primary key secara default menjadi Clustering Key dan Distribution Key. Anda dapat menggunakan primary key untuk menemukan file data, sehingga memungkinkan point query dengan queries per second (QPS) sangat tinggi dan latensi tingkat milidetik. Ini cocok untuk skenario aplikasi online seperti pengendalian risiko real-time dan rekomendasi real-time.
Rekomendasi penggunaan
Saat menetapkan primary key, pilihlah kolom yang memiliki makna bisnis. Hindari penggunaan kolom bertipe `SERIAL` sebagai primary key karena tipe ini menggunakan table lock selama proses penulisan, yang menurunkan performa, serta rentan mengalami overflow seiring pertumbuhan data.
Batasan
Primary key harus berupa kolom atau kombinasi kolom yang unik dan tidak null. Anda hanya dapat menetapkan beberapa kolom sebagai composite primary key dalam satu pernyataan DDL.
Composite primary key dapat terdiri dari maksimal 32 kolom.
Anda tidak dapat menetapkan kolom bertipe data kompleks seperti `FLOAT`, `DOUBLE`, `NUMERIC`, `ARRAY`, `JSON`, `JSONB`, `DATE`, atau tipe lainnya sebagai primary key. Hologres versi V1.3.22 ke atas mendukung penggunaan kolom bertipe `DATE` sebagai primary key. Untuk menggunakan kolom bertipe `DATE` sebagai primary key, periksa versi instans Hologres Anda dan lakukan upgrade instans jika diperlukan. Untuk informasi lebih lanjut, lihat Detail instans dan Upgrade instans.
Tabel berorientasi baris dan tabel hibrida baris-kolom wajib memiliki primary key. Tabel berorientasi kolom tidak memerlukan primary key.
Primary key tidak dapat diubah. Untuk mengganti primary key, Anda harus membuat ulang tabel tersebut.
Contoh penggunaan
Contoh berikut menunjukkan sintaks untuk Hologres V2.1 ke atas. Jika instans Anda menggunakan versi V2.0 atau lebih lama, gantilah pernyataan `WITH (property = 'value')` dalam Data Definition Language (DDL) dengan pernyataan `CALL set_table_property`. Untuk informasi lebih lanjut, lihat CREATE TABLE.
Buat tabel berorientasi kolom standar dan tentukan primary key.
Sintaks untuk V2.1 ke atas:
CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id) ) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'age', event_time_column = 'reg_timestamp', bitmap_columns = 'name,class', dictionary_encoding_columns = 'class:auto' );Sintaks untuk semua versi:
BEGIN; CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint, class text, reg_timestamp timesatmptz, PRIMARY KEY (id) ); CALL set_table_property('tbl_1', 'orientation', 'column'); CALL set_table_property('tbl_1', 'distribution_key', 'id'); CALL set_table_property('tbl_1', 'clustering_key', 'age'); CALL set_table_property('tbl_1', 'event_time_column', 'reg_timestamp'); CALL set_table_property('tbl_1', 'bitmap_columns', 'name,class'); CALL set_table_property('tbl_1', 'dictionary_encoding_columns', 'class:auto'); COMMIT;
Buat tabel berorientasi kolom standar dan tentukan composite primary key dari dua kolom.
Sintaks untuk V2.1 ke atas:
CREATE TABLE tbl_1 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text NOT NULL, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id,age) ) WITH ( orientation = 'column', distribution_key = 'id', clustering_key = 'age', event_time_column = 'reg_timestamp', bitmap_columns = 'name,class', dictionary_encoding_columns = 'class:auto' );Sintaks untuk semua versi:
BEGIN; CREATE TABLE tbl_2 ( id bigint NOT NULL, name text NOT NULL, age bigint NOT NULL, class text NOT NULL, reg_timestamp timestamptz NOT NULL, PRIMARY KEY (id,age) ); CALL set_table_property('tbl_2', 'orientation', 'column'); CALL set_table_property('tbl_2', 'distribution_key', 'id'); CALL set_table_property('tbl_2', 'clustering_key', 'age'); CALL set_table_property('tbl_2', 'event_time_column', 'reg_timestamp'); CALL set_table_property('tbl_2', 'bitmap_columns', 'name,class'); CALL set_table_property('tbl_2', 'dictionary_encoding_columns', 'class:auto'); COMMIT;
Buat tabel berorientasi baris dan tentukan primary key.
Sintaks untuk V2.1 ke atas:
CREATE TABLE public.tbl_row ( id text NOT NULL, name text NOT NULL, class text, PRIMARY KEY (id) ) WITH ( orientation = 'row', distribution_key = 'id', clustering_key = 'id' );Sintaks untuk semua versi:
BEGIN; CREATE TABLE public.tbl_row ( id text NOT NULL, name text NOT NULL, class text , PRIMARY KEY (id) ); CALL set_table_property('public.tbl_row', 'orientation', 'row'); CALL set_table_property('public.tbl_row', 'clustering_key', 'id'); CALL set_table_property('public.tbl_row', 'distribution_key', 'id'); COMMIT;
Buat tabel partisi dan tentukan primary key.
Sintaks untuk V2.1 ke atas:
BEGIN; CREATE TABLE public.tbl_parent( a text , b int, c timestamp, d text, ds text, PRIMARY KEY (ds,b) ) PARTITION BY LIST(ds) WITH ( orientation = 'column'); CREATE TABLE public.tbl_child_1 PARTITION OF public.tbl_parent FOR VALUES IN('20221207'); CREATE TABLE public.tbl_child_2 PARTITION OF public.tbl_parent FOR VALUES IN('20221208'); COMMIT;Sintaks untuk semua versi:
BEGIN; CREATE TABLE public.tbl_parent( a text , b int, c timestamp, d text, ds text, PRIMARY KEY (ds,b) ) PARTITION BY LIST(ds); CALL set_table_property('public.tbl_parent', 'orientation', 'column'); CREATE TABLE public.tbl_child_1 PARTITION OF public.tbl_parent FOR VALUES IN('20221207'); CREATE TABLE public.tbl_child_2 PARTITION OF public.tbl_parent FOR VALUES IN('20221208'); COMMIT;
Referensi
Untuk panduan menetapkan properti tabel yang sesuai berdasarkan skenario kueri Anda, lihat Panduan berbasis skenario untuk pembuatan dan optimasi tabel.
Untuk praktik terbaik dalam pembuatan tabel dan kueri pada skenario kueri key-value (KV), lihat Praktik terbaik untuk skenario kueri Key/Value.
Untuk informasi lebih lanjut mengenai pernyataan DDL untuk tabel internal Hologres, lihat: