Halaman ini membahas persyaratan skema Spanner, cara menggunakan skema untuk membuat hubungan hierarkis, dan fitur skema. Versi ini juga memperkenalkan tabel yang diselingi, yang dapat meningkatkan performa kueri saat membuat kueri tabel dalam hubungan induk-turunan.
Skema adalah namespace yang berisi objek database, seperti tabel, tampilan, indeks, dan fungsi. Anda menggunakan skema untuk mengatur objek, menerapkan hak istimewa kontrol akses terperinci, dan menghindari konflik penamaan. Anda harus menentukan skema untuk setiap database di Spanner.
Anda juga dapat menyegmentasikan dan menyimpan baris lebih lanjut di tabel database di seluruh wilayah geografis yang berbeda. Untuk informasi selengkapnya, lihat Ringkasan partisi geografis.
Data dengan jenis yang kuat
Data di Spanner memiliki jenis yang dikenali. Jenis data mencakup jenis skalar dan kompleks, yang dijelaskan dalam Jenis data di GoogleSQL dan Jenis data PostgreSQL.
Pilih kunci utama
Database Spanner dapat berisi satu atau beberapa tabel. Tabel disusun sebagai baris dan kolom. Skema tabel menentukan satu atau beberapa kolom tabel sebagai kunci utama tabel yang mengidentifikasi setiap baris secara unik. Kunci utama selalu diindeks untuk pencarian baris cepat. Jika Anda ingin memperbarui atau menghapus baris yang ada dalam tabel, tabel tersebut harus memiliki kunci utama. Tabel tanpa kolom kunci utama hanya dapat memiliki satu baris. Hanya database dialek GoogleSQL yang dapat memiliki tabel tanpa kunci utama.
Sering kali aplikasi Anda sudah memiliki kolom yang cocok untuk digunakan sebagai
kunci utama. Misalnya, untuk tabel Customers
, mungkin ada
CustomerId
yang disediakan aplikasi yang berfungsi dengan baik sebagai kunci utama. Dalam kasus
lain, Anda mungkin perlu membuat kunci utama saat menyisipkan baris. Nilai ini
biasanya berupa nilai bilangan bulat unik tanpa signifikansi bisnis (kunci utama pengganti).
Dalam semua kasus, Anda harus berhati-hati agar tidak membuat hotspot dengan pilihan kunci utama. Misalnya, jika Anda menyisipkan data dengan bilangan bulat yang meningkat secara monoton sebagai kunci, Anda akan selalu menyisipkan di akhir ruang kunci. Hal ini tidak diinginkan karena Spanner membagi data di antara server berdasarkan rentang kunci, yang berarti penyisipan Anda akan diarahkan ke satu server, sehingga membuat hotspot. Ada teknik yang dapat menyebarkan beban di beberapa server dan menghindari hotspot:
- Lakukan hashing pada kunci, lalu simpan di kolom. Gunakan kolom hash (atau kolom hash dan kolom kunci unik secara bersamaan) sebagai kunci utama.
- Tukar urutan kolom dalam kunci utama.
- Gunakan ID Unik Universal (UUID). UUID versi 4 direkomendasikan, karena menggunakan nilai acak dalam bit urutan tinggi. Jangan gunakan algoritma UUID (seperti UUID versi 1) yang menyimpan stempel waktu dalam bit urutan tinggi.
- Lakukan bit-reverse pada nilai berurutan.
Hubungan tabel induk-turunan
Ada dua cara untuk menentukan hubungan induk-turunan di Spanner: interleave tabel dan kunci asing.
Interleaving tabel Spanner adalah pilihan yang tepat untuk banyak
hubungan induk-turunan. Dengan interleaving, Spanner secara fisik
meletakkan baris turunan dengan baris induk dalam penyimpanan. Lokasi yang sama dapat meningkatkan performa secara signifikan. Misalnya, jika Anda memiliki tabel Customers
dan
tabel Invoices
, dan aplikasi Anda sering mengambil semua invoice untuk
pelanggan, Anda dapat menentukan Invoices
sebagai tabel turunan yang diselingi dari
Customers
. Dengan demikian, Anda mendeklarasikan hubungan lokalitas data antara
dua tabel independen. Anda memberi tahu Spanner untuk menyimpan satu atau beberapa baris Invoices
dengan satu baris Customers
.
Anda mengaitkan tabel turunan dengan tabel induk menggunakan DDL yang mendeklarasikan tabel turunan sebagai sisipan di induk, dan dengan menyertakan kunci utama tabel induk sebagai bagian pertama dari kunci utama gabungan tabel turunan. Untuk informasi selengkapnya tentang interleaving, lihat Membuat tabel interleaved nanti di halaman ini.
Kunci asing adalah solusi induk-turunan yang lebih umum dan menangani kasus penggunaan tambahan. Tabel tidak terbatas pada kolom kunci utama, dan tabel dapat memiliki beberapa hubungan kunci asing, baik sebagai induk dalam beberapa hubungan maupun turunan dalam hubungan lainnya. Namun, hubungan kunci asing tidak menyiratkan lokasi yang sama untuk tabel di lapisan penyimpanan.
Google merekomendasikan agar Anda memilih untuk mewakili hubungan induk-turunan sebagai tabel interleave atau sebagai kunci asing, tetapi tidak keduanya. Untuk informasi selengkapnya tentang kunci asing dan perbandingannya dengan tabel yang diselingi, lihat Ringkasan kunci asing.
Kunci utama dalam tabel sisipan
Untuk interleaving, setiap tabel harus memiliki kunci utama. Jika Anda mendeklarasikan tabel menjadi turunan yang diselingi dari tabel lain, tabel harus memiliki kunci utama komposit yang menyertakan semua komponen kunci utama induk, dalam urutan yang sama, dan, biasanya, satu atau beberapa kolom tabel turunan tambahan.
Spanner menyimpan baris dalam urutan yang diurutkan berdasarkan nilai kunci utama, dengan baris turunan disisipkan di antara baris induk. Lihat ilustrasi baris sisipan di Membuat tabel sisipan nanti di halaman ini.
Singkatnya, Spanner dapat menempatkan baris tabel terkait secara fisik di tempat yang sama. Contoh skema menunjukkan tampilan tata letak fisik ini.
Pemisahan database
Anda dapat menentukan hierarki hubungan induk-turunan yang saling tumpang-tindih hingga tujuh lapisan, yang berarti Anda dapat menempatkan baris dari tujuh tabel independen secara berdampingan. Jika ukuran data dalam tabel Anda kecil, satu server Spanner mungkin dapat menangani database Anda. Namun, apa yang terjadi jika tabel terkait Anda bertambah dan mulai mencapai batas resource server individual? Spanner adalah database terdistribusi, yang berarti bahwa seiring berkembangnya database, Spanner membagi data Anda menjadi beberapa bagian yang disebut "bagian". Setiap bagian dapat berpindah secara independen dari satu sama lain dan ditetapkan ke server yang berbeda, yang dapat berada di lokasi fisik yang berbeda. Pemisahan menyimpan rentang baris yang berdekatan. Kunci awal dan akhir rentang ini disebut "batas pemisahan". Spanner secara otomatis menambahkan dan menghapus batas pemisahan berdasarkan ukuran dan beban, yang mengubah jumlah pemisahan dalam database.
Pembagian berbasis beban
Sebagai contoh cara Spanner melakukan pemisahan berbasis beban untuk memitigasi hotspot baca, misalkan database Anda berisi tabel dengan 10 baris yang lebih sering dibaca daripada semua baris lain dalam tabel. Spanner dapat menambahkan batas pemisahan di antara setiap 10 baris tersebut sehingga setiap baris ditangani oleh server yang berbeda, bukan mengizinkan semua pembacaan baris tersebut menggunakan resource satu server.
Sebagai aturan umum, jika Anda mengikuti praktik terbaik untuk desain skema, Spanner dapat mengurangi hotspot sehingga throughput baca akan meningkat setiap beberapa menit hingga Anda memenuhi resource di instance atau mengalami kasus saat tidak ada batas pemisahan baru yang dapat ditambahkan (karena Anda memiliki pemisahan yang hanya mencakup satu baris tanpa turunan yang diselingi).
Skema bernama
Skema bernama membantu Anda mengatur data serupa secara bersamaan. Hal ini membantu Anda menemukan objek dengan cepat di konsol Google Cloud, menerapkan hak istimewa, dan menghindari konflik penamaan.
Skema bernama, seperti objek database lainnya, dikelola menggunakan DDL.
Skema bernama Spanner memungkinkan Anda menggunakan nama yang sepenuhnya memenuhi syarat
(FQN) untuk membuat kueri data. FQN memungkinkan Anda menggabungkan nama skema dan
nama objek untuk mengidentifikasi objek database. Misalnya, Anda dapat membuat skema
yang disebut warehouse
untuk unit bisnis gudang. Tabel yang menggunakan skema ini dapat mencakup: product
, order
, dan customer information
. Atau, Anda
dapat membuat skema bernama fulfillment
untuk unit bisnis fulfillment.
Skema ini juga dapat memiliki tabel yang disebut product
, order
, dan customer
information
. Pada contoh pertama, FQN adalah warehouse.product
dan pada
contoh kedua, FQN adalah fulfillment.product
. Hal ini mencegah kebingungan dalam situasi saat beberapa objek memiliki nama yang sama.
Dalam DDL CREATE SCHEMA
, objek tabel diberi FQN, misalnya,
sales.customers
, dan nama singkat, misalnya, sales
.
Objek database berikut mendukung skema bernama:
TABLE
CREATE
INTERLEAVE IN [PARENT]
FOREIGN KEY
SYNONYM
VIEW
INDEX
FOREIGN KEY
SEQUENCE
Untuk mengetahui informasi selengkapnya tentang penggunaan skema bernama, lihat Mengelola skema bernama.
Menggunakan kontrol akses yang sangat terperinci dengan skema bernama
Skema bernama memungkinkan Anda memberikan akses tingkat skema ke setiap objek dalam skema. Hal ini berlaku untuk objek skema yang ada pada saat Anda memberikan akses. Anda harus memberikan akses ke objek yang ditambahkan nanti.
Kontrol akses terperinci membatasi akses ke seluruh grup objek database, seperti tabel, kolom, dan baris dalam tabel.
Untuk informasi selengkapnya, lihat Memberikan hak istimewa kontrol akses terperinci ke skema bernama.
Contoh skema
Contoh skema di bagian ini menunjukkan cara membuat tabel induk dan turunan dengan dan tanpa interleaving, serta mengilustrasikan tata letak fisik data yang sesuai.
Membuat tabel induk
Misalnya, Anda membuat aplikasi musik dan memerlukan tabel yang menyimpan baris data penyanyi:
Perhatikan bahwa tabel berisi satu kolom kunci utama, SingerId
, yang muncul
di sebelah kiri baris yang dicetak tebal, dan tabel diatur berdasarkan baris dan
kolom.
Anda dapat menentukan tabel dengan DDL berikut:
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId);
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA );
Perhatikan hal-hal berikut tentang contoh skema:
Singers
adalah tabel di root hierarki database (karena tidak ditentukan sebagai turunan yang diselingi dari tabel lain).- Untuk database dialek GoogleSQL, kolom kunci utama biasanya dianotasi dengan
NOT NULL
(meskipun Anda dapat menghapus anotasi ini jika ingin mengizinkan nilaiNULL
di kolom kunci. Untuk informasi selengkapnya, lihat Kolom Kunci). - Kolom yang tidak disertakan dalam kunci utama disebut kolom non-kunci,
dan dapat memiliki anotasi
NOT NULL
opsional. - Kolom yang menggunakan jenis
STRING
atauBYTES
di GoogleSQL harus ditentukan dengan panjang, yang mewakili jumlah maksimum karakter Unicode yang dapat disimpan di kolom. Spesifikasi panjang bersifat opsional untuk jenis PostgreSQLvarchar
dancharacter varying
. Untuk informasi selengkapnya, lihat Jenis Data Skalar untuk database dialek GoogleSQL dan jenis data PostgreSQL untuk database dialek PostgreSQL.
Seperti apa tata letak fisik baris dalam tabel Singers
? Diagram
berikut menunjukkan baris tabel Singers
yang disimpan oleh kunci utama
("Singers(1)", lalu "Singers(2)", dengan angka dalam tanda kurung adalah
nilai kunci utama.
Diagram sebelumnya mengilustrasikan contoh batas pemisahan antara baris yang diberi kunci oleh Singers(3)
dan Singers(4)
, dengan data dari pemisahan yang dihasilkan ditetapkan ke server yang berbeda. Seiring bertambahnya tabel ini, baris data
Singers
dapat disimpan di lokasi yang berbeda.
Membuat tabel induk dan turunan
Anggaplah sekarang Anda ingin menambahkan beberapa data dasar tentang album setiap penyanyi ke aplikasi musik.
Perhatikan bahwa kunci utama Albums
terdiri dari dua kolom: SingerId
dan
AlbumId
, untuk mengaitkan setiap album dengan penyanyinya. Contoh skema berikut
menentukan tabel Albums
dan Singers
di root hierarki database, yang menjadikannya tabel saudara.
-- Schema hierarchy: -- + Singers (sibling table of Albums) -- + Albums (sibling table of Singers)
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId);
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA ); CREATE TABLE albums ( singer_id BIGINT, album_id BIGINT, album_title VARCHAR, PRIMARY KEY (singer_id, album_id) );
Tata letak fisik baris Singers
dan Albums
terlihat seperti
diagram berikut, dengan baris tabel Albums
yang disimpan oleh kunci utama
yang berdekatan, lalu baris Singers
yang disimpan oleh kunci utama yang berdekatan:
Satu catatan penting tentang skema adalah Spanner tidak mengasumsikan
hubungan lokalitas data antara tabel Singers
dan Albums
, karena
tabel tersebut adalah tabel tingkat teratas. Seiring berkembangnya database, Spanner dapat menambahkan
batas pemisahan di antara baris mana pun. Artinya, baris tabel Albums
dapat berakhir dalam pemisahan yang berbeda dari baris tabel Singers
,
dan kedua pemisahan tersebut dapat bergerak secara independen satu sama lain.
Bergantung pada kebutuhan aplikasi Anda, Anda dapat mengizinkan data Albums
berada di bagian yang berbeda dari data Singers
. Namun, hal ini dapat menimbulkan
dampak negatif pada performa karena perlunya mengoordinasikan pembacaan dan pembaruan di seluruh
resource yang berbeda. Jika aplikasi Anda sering kali perlu mengambil informasi
tentang semua album untuk penyanyi tertentu, Anda harus membuat Albums
sebagai
tabel turunan interleaved dari Singers
, yang menempatkan baris dari dua
tabel di sepanjang dimensi kunci utama. Contoh berikutnya menjelaskan hal ini secara lebih
mendetail.
Membuat tabel sisipan
Tabel sisipan adalah tabel yang Anda deklarasikan sebagai turunan sisipan dari tabel lain karena Anda ingin baris tabel turunan disimpan secara fisik dengan baris induk terkait. Seperti yang disebutkan sebelumnya, kunci utama tabel induk harus menjadi bagian pertama dari kunci utama gabungan tabel turunan.
Setelah Anda menyisipkan tabel, tabel tersebut akan diubah secara permanen. Anda tidak dapat mengurungkan interleaving. Sebagai gantinya, Anda perlu membuat tabel lagi dan memigrasikan data ke tabel tersebut.
Saat mendesain aplikasi musik, Anda menyadari bahwa aplikasi
harus sering mengakses baris dari tabel Albums
saat mengakses
baris Singers
. Misalnya, saat mengakses baris Singers(1)
, Anda juga perlu
mengakses baris Albums(1, 1)
dan Albums(1, 2)
. Dalam hal ini, Singers
dan Albums
harus memiliki hubungan lokalitas data yang kuat. Anda dapat mendeklarasikan
hubungan lokalitas data ini dengan membuat Albums
sebagai tabel turunan
interleaved dari Singers
.
-- Schema hierarchy: -- + Singers -- + Albums (interleaved table, child table of Singers)
Baris yang dicetak tebal dalam skema berikut menunjukkan cara membuat Albums
sebagai
tabel interleaved Singers
.
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA ); CREATE TABLE albums ( singer_id BIGINT, album_id BIGINT, album_title VARCHAR, PRIMARY KEY (singer_id, album_id) ) INTERLEAVE IN PARENT singers ON DELETE CASCADE;
Catatan tentang skema ini:
SingerId
, yang merupakan bagian pertama dari kunci utama tabel turunanAlbums
, juga merupakan kunci utama tabel induknyaSingers
.- Anotasi
ON DELETE CASCADE
menandakan bahwa saat baris dari tabel induk dihapus, baris turunannya juga akan otomatis dihapus. Jika tabel turunan tidak memiliki anotasi ini, atau anotasi adalahON DELETE NO ACTION
, Anda harus menghapus baris turunan sebelum dapat menghapus baris induk. - Baris yang disisipkan diurutkan terlebih dahulu berdasarkan baris tabel induk, lalu berdasarkan baris yang berdekatan dari tabel turunan yang memiliki kunci utama induk. Misalnya, "Penyanyi(1)", lalu "Album(1, 1)", lalu "Album(1, 2)".
- Hubungan lokalitas data setiap penyanyi dan data albumnya
akan dipertahankan jika database ini terpecah, asalkan ukuran baris
Singers
dan semua barisAlbums
-nya tetap di bawah batas ukuran pemisahan dan tidak ada hotspot di salah satu barisAlbums
ini. - Baris induk harus ada sebelum Anda dapat menyisipkan baris turunan. Baris induk dapat sudah ada di database atau dapat disisipkan sebelum penyisipan baris turunan dalam transaksi yang sama.
Membuat hierarki tabel yang diselang-seling
Hubungan induk-turunan antara Singers
dan Albums
dapat diperluas ke
tabel turunan lainnya. Misalnya, Anda dapat membuat tabel interleaved
yang disebut Songs
sebagai turunan dari Albums
untuk menyimpan daftar lagu setiap album:
Songs
harus memiliki kunci utama yang menyertakan semua kunci utama tabel
yang berada di tingkat yang lebih tinggi dalam hierarki, yaitu SingerId
dan AlbumId
.
-- Schema hierarchy: -- + Singers -- + Albums (interleaved table, child table of Singers) -- + Songs (interleaved table, child table of Albums)
GoogleSQL
CREATE TABLE Singers ( SingerId INT64 NOT NULL, FirstName STRING(1024), LastName STRING(1024), SingerInfo BYTES(MAX), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE; CREATE TABLE Songs ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, TrackId INT64 NOT NULL, SongName STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId, TrackId), INTERLEAVE IN PARENT Albums ON DELETE CASCADE;
PostgreSQL
CREATE TABLE singers ( singer_id BIGINT PRIMARY KEY, first_name VARCHAR(1024), last_name VARCHAR(1024), singer_info BYTEA ); CREATE TABLE albums ( singer_id BIGINT, album_id BIGINT, album_title VARCHAR, PRIMARY KEY (singer_id, album_id) ) INTERLEAVE IN PARENT singers ON DELETE CASCADE; CREATE TABLE songs ( singer_id BIGINT, album_id BIGINT, track_id BIGINT, song_name VARCHAR, PRIMARY KEY (singer_id, album_id, track_id) ) INTERLEAVE IN PARENT albums ON DELETE CASCADE;
Diagram berikut menunjukkan tampilan fisik baris yang diselingi.
Dalam contoh ini, seiring bertambahnya jumlah penyanyi, Spanner menambahkan batas pemisahan antara penyanyi untuk mempertahankan lokalitas data antara penyanyi dan data album dan lagunya. Namun, jika ukuran baris penyanyi dan baris turunannya melebihi batas ukuran pemisahan, atau hotspot terdeteksi di baris turunan, Spanner akan mencoba menambahkan batas pemisahan untuk mengisolasi baris hotspot tersebut beserta semua baris turunan di bawahnya.
Singkatnya, tabel induk beserta semua tabel turunan dan turunannya membentuk hierarki tabel dalam skema. Meskipun setiap tabel dalam hierarki bersifat independen secara logis, secara fisik menyisipkan tabel dengan cara ini dapat meningkatkan performa, yang secara efektif menggabungkan tabel dan memungkinkan Anda mengakses baris terkait secara bersamaan sekaligus meminimalkan akses penyimpanan.
Gabungan dengan tabel sisipan
Jika memungkinkan, gabungkan data dalam tabel yang diselingi berdasarkan kunci utama. Karena setiap
baris yang diselingi biasanya disimpan secara fisik dalam bagian yang sama dengan baris
induk, Spanner dapat melakukan join berdasarkan kunci utama secara lokal, sehingga meminimalkan
akses penyimpanan dan traffic jaringan. Dalam contoh berikut, Singers
dan
Albums
digabungkan pada kunci utama SingerId
.
GoogleSQL
SELECT s.FirstName, a.AlbumTitle FROM Singers AS s JOIN Albums AS a ON s.SingerId = a.SingerId;
PostgreSQL
SELECT s.first_name, a.album_title FROM singers AS s JOIN albums AS a ON s.singer_id = a.singer_id;
Kolom utama
Bagian ini mencakup beberapa catatan tentang kolom utama.
Mengubah kunci tabel
Kunci tabel tidak dapat berubah; Anda tidak dapat menambahkan kolom kunci ke tabel yang ada atau menghapus kolom kunci dari tabel yang ada.
Menyimpan NULL dalam kunci utama
Di GoogleSQL, jika Anda ingin menyimpan NULL di kolom kunci utama,
hapus klausa NOT NULL
untuk kolom tersebut dalam skema. (Database dialek PostgreSQL tidak
mendukung NULL di kolom kunci utama.)
Berikut adalah contoh penghapusan klausa NOT NULL
pada kolom kunci utama
SingerId
. Perhatikan bahwa karena SingerId
adalah kunci utama, hanya boleh ada
satu baris yang menyimpan NULL
di kolom tersebut.
CREATE TABLE Singers ( SingerId INT64, FirstName STRING(1024), LastName STRING(1024), ) PRIMARY KEY (SingerId);
Properti nullable kolom kunci utama harus cocok antara deklarasi tabel induk dan turunan. Dalam contoh ini, NOT NULL
untuk kolom
Albums.SingerId
tidak diizinkan karena Singers.SingerId
menghapusnya.
CREATE TABLE Singers ( SingerId INT64, FirstName STRING(1024), LastName STRING(1024), ) PRIMARY KEY (SingerId); CREATE TABLE Albums ( SingerId INT64 NOT NULL, AlbumId INT64 NOT NULL, AlbumTitle STRING(MAX), ) PRIMARY KEY (SingerId, AlbumId), INTERLEAVE IN PARENT Singers ON DELETE CASCADE;
Jenis yang tidak diizinkan
Kolom berikut tidak boleh berjenis ARRAY
:
- Kolom kunci tabel.
- Kolom kunci indeks.
Mendesain untuk multi-tenancy
Anda mungkin ingin menerapkan multi-tenancy jika menyimpan data milik pelanggan yang berbeda. Misalnya, layanan musik mungkin ingin menyimpan setiap konten label rekaman secara terpisah.
Multi-tenancy klasik
Cara klasik untuk mendesain multi-tenancy adalah dengan membuat database terpisah untuk
setiap pelanggan. Dalam contoh ini, setiap database memiliki tabel Singers
-nya sendiri:
SingerId | FirstName | LastName |
---|---|---|
1 | Marc | Richards |
2 | Catalina | Smith |
SingerId | FirstName | LastName |
---|---|---|
1 | Alice | Trentor |
2 | Gabriel | Wright |
SingerId | FirstName | LastName |
---|---|---|
1 | Benjamin | Martinez |
2 | Hannah | Harris |
Multi-tenancy yang dikelola skema
Cara lain untuk mendesain multi-tenancy di Spanner adalah dengan menempatkan semua
pelanggan dalam satu tabel dalam satu database, dan menggunakan nilai kunci utama
yang berbeda untuk setiap pelanggan. Misalnya, Anda dapat menyertakan kolom kunci CustomerId
dalam tabel. Jika Anda menjadikan CustomerId
sebagai kolom kunci pertama, data untuk setiap pelanggan akan memiliki lokalitas yang baik. Spanner
kemudian dapat menggunakan pemisahan database secara efektif untuk memaksimalkan
performa berdasarkan ukuran data dan pola beban. Dalam contoh berikut,
ada satu tabel Singers
untuk semua pelanggan:
CustomerId | SingerId | FirstName | LastName |
---|---|---|---|
1 | 1 | Marc | Richards |
1 | 2 | Catalina | Smith |
2 | 1 | Alice | Trentor |
2 | 2 | Gabriel | Wright |
3 | 1 | Benjamin | Martinez |
3 | 2 | Hannah | Harris |
Jika Anda harus memiliki database terpisah untuk setiap tenant, ada batasan yang harus diperhatikan:
- Ada batasan jumlah database per instance dan jumlah tabel dan indeks per database. Bergantung pada jumlah pelanggan, Anda mungkin tidak dapat memiliki database atau tabel terpisah.
- Menambahkan tabel baru dan indeks non-interleaved dapat memerlukan waktu yang lama. Anda mungkin tidak dapat mendapatkan performa yang diinginkan jika desain skema Anda bergantung pada penambahan tabel dan indeks baru.
Jika ingin membuat database terpisah, Anda mungkin akan lebih berhasil jika mendistribusikan tabel ke seluruh database sedemikian rupa sehingga setiap database memiliki jumlah perubahan skema yang rendah per minggu.
Jika Anda membuat tabel dan indeks terpisah untuk setiap pelanggan aplikasi, jangan tempatkan semua tabel dan indeks dalam database yang sama. Sebagai gantinya, bagi data tersebut ke banyak database, untuk mengurangi masalah performa dengan membuat banyak indeks.
Untuk mempelajari lebih lanjut pola pengelolaan data dan desain aplikasi lainnya untuk multi-tenancy, lihat Menerapkan Multi-Tenancy di Spanner