PostgreSQL: Apakah lebih baik menggunakan banyak basis data dengan satu skema masing-masing, atau satu database dengan banyak skema?


147

Setelah komentar ini ke salah satu pertanyaan saya, saya berpikir apakah lebih baik menggunakan satu database dengan skema X atau sebaliknya.

Situasi saya: Saya sedang mengembangkan aplikasi web di mana, ketika orang mendaftar, saya membuat (sebenarnya) database (tidak, itu bukan jejaring sosial: semua orang harus memiliki akses ke datanya sendiri dan tidak pernah melihat data pengguna lain) .

Itulah cara saya menggunakan versi aplikasi saya sebelumnya (yang masih berjalan di MySQL): melalui API Plesk, untuk setiap pendaftaran, saya lakukan:

  1. Buat pengguna basis data dengan hak istimewa terbatas;
  2. Buat database yang dapat diakses hanya oleh pengguna yang dibuat sebelumnya dan superuser (untuk pemeliharaan)
  3. Mengisi basis data

Sekarang, saya harus melakukan hal yang sama dengan PostgreSQL (proyek semakin matang dan MySQL ... tidak memenuhi semua kebutuhan).

Saya harus memiliki semua cadangan basis data / skema independen: pg_dump berfungsi dengan baik dalam dua cara, dan hal yang sama untuk pengguna yang dapat dikonfigurasi untuk mengakses hanya satu skema atau satu database.

Jadi, dengan anggapan Anda adalah pengguna PostgreSQL yang lebih berpengalaman daripada saya, menurut Anda apa solusi terbaik untuk situasi saya, dan mengapa?

Apakah akan ada perbedaan kinerja menggunakan basis data $ x bukannya skema $ x? Dan solusi apa yang akan lebih baik untuk dipertahankan di masa depan (keandalan)?

Semua database / skema saya akan selalu memiliki struktur yang sama!

Untuk masalah backup (menggunakan pg_dump), mungkin lebih baik menggunakan satu database dan banyak skema, membuang semua skema sekaligus: memulihkan akan cukup sederhana memuat dump utama dalam mesin pengembangan dan kemudian membuang dan mengembalikan hanya skema yang diperlukan: ada adalah satu langkah tambahan, tetapi membuang semua skema tampaknya lebih cepat daripada membuangnya satu per satu.

UPDATE 2012

Nah, struktur dan desain aplikasi berubah sangat banyak selama dua tahun terakhir. Saya masih menggunakan one db with many schemaspendekatan, tetapi masih, saya punya satu database untuk setiap versi aplikasi saya:

Db myapp_01
    \_ my_customer_foo_schema
    \_ my_customer_bar_schema
Db myapp_02
    \_ my_customer_foo_schema
    \_ my_customer_bar_schema

Untuk cadangan, saya membuang setiap basis data secara teratur, dan kemudian memindahkan cadangan pada server pengembangan.

Saya juga menggunakan cadangan PITR / WAL tetapi, seperti yang saya katakan sebelumnya, tidak mungkin saya harus mengembalikan semua database sekaligus ... jadi mungkin akan diberhentikan tahun ini (dalam situasi saya bukan pendekatan terbaik ).

Pendekatan satu-db-banyak-skema bekerja sangat baik bagi saya sejak sekarang, bahkan jika struktur aplikasi benar-benar berubah:

Saya hampir lupa: semua database / skema saya akan selalu memiliki struktur yang sama!

... sekarang, setiap skema memiliki strukturnya sendiri yang berubah secara dinamis bereaksi terhadap aliran data pengguna.


"Semua database / skema saya akan memiliki struktur yang sama!" maksud Anda mereka semua memiliki struktur yang sama? Atau tidak pernah?
Osama Al-Maadeed

Maaf, ya, mereka semua memiliki struktur yang sama selamanya: jika saya mengubahnya, saya akan mengubah semuanya;)
Strae

Jika Anda memiliki 1000 pelanggan, itu artinya Anda harus memperbarui 1000 skema?
Joshua Partogi

@jpartogi: ya, tetapi saya harus memperbarui hanya struktur tabel, bukan data.
Strae

Jadi, untuk apa kamu akhirnya? Namun, satu pertanyaan, meskipun kinerja kueri, dll. Dapat dikontrol oleh tablespace, skema yang menghasilkan kinerja setara multi-db vs multi-skema, dampak apa pun pada log WAL ???
Kapil

Jawaban:


113

"Skema" PostgreSQL kira-kira sama dengan "database" MySQL. Memiliki banyak basis data pada instalasi PostgreSQL dapat menjadi masalah; memiliki banyak skema akan bekerja tanpa masalah. Jadi Anda pasti ingin menggunakan satu database dan beberapa skema dalam database itu.


33
Ini. Postgres tidak memungkinkan Anda melakukan kueri di seluruh basis data, yang bisa sangat menjengkelkan.
matt b

81
"Memiliki banyak basis data pada instalasi PostgreSQL dapat menimbulkan masalah" - mohon klarifikasi; apakah itu bermasalah secara umum atau dalam kasus khusus ini, dan mengapa?
akaihola

33
"Kasus penggunaan yang paling umum untuk menggunakan beberapa skema dalam database adalah membangun aplikasi perangkat lunak-sebagai-layanan di mana setiap pelanggan memiliki skema mereka sendiri. Meskipun teknik ini tampaknya menarik, kami sangat merekomendasikannya karena telah menyebabkan banyak kasus masalah operasional. Misalnya, bahkan sejumlah kecil skema (> 50) dapat sangat memengaruhi kinerja alat snapshot basis data Heroku " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan

16
@NeilMcGuigan: Menariknya, itu sepertinya merupakan kesimpulan yang berlawanan dari jawaban kquinn (diterima).
carbocation

8
Memiliki satu database dengan banyak skema akan membuatnya hampir tidak mungkin untuk membuang satu skema dari mereka. Saya menjalankan database postgres tunggal dengan lebih dari 3000 skema dan pg_dump gagal dengan kesalahan kehabisan memori jika Anda mencoba untuk membuang satu skema. Saya ingin tahu apakah ini akan berbeda jika saya memiliki 3.000 database sebagai gantinya.
Machisuji

27

Jelas, saya akan pergi untuk pendekatan satu-db-banyak-skema. Ini memungkinkan saya untuk membuang semua basis data, tetapi mengembalikan hanya satu dengan sangat mudah, dengan banyak cara:

  1. Buang db (semua skema), muat dump di db baru, buang saja skema yang saya butuhkan, dan kembalikan kembali ke db utama.
  2. Buang skema secara terpisah, satu per satu (tapi saya pikir mesin akan lebih menderita dengan cara ini - dan saya mengharapkan 500 skema!)

Kalau tidak, googling di sekitar saya telah melihat bahwa tidak ada prosedur otomatis untuk menduplikasi skema (menggunakan satu sebagai templat), tetapi banyak yang menyarankan cara ini:

  1. Buat skema-templat
  2. Saat perlu menggandakan, ganti nama dengan nama baru
  3. Buang itu
  4. Ganti nama kembali
  5. Kembalikan dump
  6. Keajaiban sudah selesai.

Saya telah menulis dua baris dengan Python untuk melakukan itu; Saya berharap mereka dapat membantu seseorang (dalam kode 2-detik-ditulis, jangan menggunakannya dalam produksi):

import os
import sys
import pg

# Take the new schema name from the second cmd arguments (the first is the filename)
newSchema = sys.argv[1]

# Temperary folder for the dumps
dumpFile = '/test/dumps/' + str(newSchema) + '.sql'

# Settings
db_name = 'db_name'
db_user = 'db_user'
db_pass = 'db_pass'
schema_as_template = 'schema_name'

# Connection
pgConnect = pg.connect(dbname= db_name, host='localhost', user= db_user, passwd= db_pass)

# Rename schema with the new name
pgConnect.query("ALTER SCHEMA " + schema_as_template + " RENAME TO " + str(newSchema))

# Dump it
command = 'export PGPASSWORD="' + db_pass + '" && pg_dump -U ' + db_user + ' -n ' + str(newSchema) + ' ' + db_name + ' > ' + dumpFile
os.system(command)

# Rename back with its default name
pgConnect.query("ALTER SCHEMA " + str(newSchema) + " RENAME TO " + schema_as_template)

# Restore the previous dump to create the new schema
restore = 'export PGPASSWORD="' + db_pass + '" && psql -U ' + db_user + ' -d ' + db_name + ' < ' + dumpFile
os.system(restore)

# Want to delete the dump file?
os.remove(dumpFile)

# Close connection
pgConnect.close()

14

Saya akan mengatakan, pergi dengan banyak database DAN beberapa skema :)

Skema di PostgreSQL sangat mirip dengan paket di Oracle, jika Anda terbiasa dengan itu. Basis data dimaksudkan untuk membedakan antara seluruh set data, sedangkan skema lebih seperti entitas data.

Misalnya, Anda bisa memiliki satu database untuk seluruh aplikasi dengan skema "UserManagement", "LongTermStorage" dan sebagainya. "Manajemen Pengguna" kemudian akan berisi tabel "Pengguna", serta semua prosedur, pemicu, urutan, dll yang tersimpan yang diperlukan untuk manajemen pengguna.

Basis data adalah keseluruhan program, skema adalah komponen.


4
... dan saya akan memiliki 1 basis data, dengan di dalam skema: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? Mh ... sepertinya bukan cara yang dapat diandalkan ... dan bagaimana dengan kinerja? Dan bagaimana dengan kode aplikasi saya (akan php dan python)? begitu banyak skema ..
Strae

7
@ Trae: Saya membaca ini sebagai: setiap pelanggan memiliki basis data itu customer1_database, customer2_database dan di dalam basis data tersebut Anda memiliki user_schema, document_schema.
frankhommers

6

Dalam konteks PostgreSQL saya sarankan untuk menggunakan satu db dengan banyak skema, karena Anda dapat (misalnya) UNION ALL di seluruh skema, tetapi tidak di seluruh database. Untuk alasan itu, sebuah basis data benar-benar terisolasi dari basis data lain sementara skema tidak terisolasi dari skema lain dalam basis data yang sama.

Jika Anda - karena alasan tertentu - harus mengkonsolidasikan data di seluruh skema di masa mendatang, akan mudah untuk melakukan ini di beberapa skema. Dengan banyak basis data, Anda akan membutuhkan banyak koneksi db dan mengumpulkan dan menggabungkan data dari setiap basis data "secara manual" dengan logika aplikasi.

Yang terakhir memiliki kelebihan dalam beberapa kasus, tetapi untuk bagian utama saya pikir pendekatan satu-database-banyak-skema lebih berguna.


4

Sejumlah skema harus lebih ringan daripada sejumlah database, meskipun saya tidak dapat menemukan referensi yang menegaskan hal ini.

Tetapi jika Anda benar-benar ingin menjaga hal-hal yang sangat terpisah (alih-alih refactoring aplikasi web sehingga kolom "pelanggan" ditambahkan ke tabel Anda), Anda mungkin masih ingin menggunakan database terpisah: Saya menegaskan bahwa Anda dapat lebih mudah membuat pemulihan database pelanggan tertentu dengan cara ini - tanpa mengganggu pelanggan lain.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.