PostgreSQL: Her biri bir şema ile birden fazla veritabanı veya birden fazla şema ile bir veritabanı kullanmak daha mı iyi?


147

Benim soru birine bu yorumdan sonra , X şemaları ile bir veritabanı kullanarak daha iyi olup olmadığını düşünüyorum ya da tam tersi.

Benim durumum: İnsanlar kaydolduğunda, bir veritabanı (aslında) oluşturduğum bir web uygulaması geliştiriyorum (hayır, bu bir sosyal ağ değil: herkes kendi verilerine erişmeli ve diğer kullanıcının verilerini asla görmemelidir) .

Uygulamamın önceki sürümü için kullandığım yol budur (hala MySQL'de çalışıyor): Plesk API'sı aracılığıyla, her kayıt için şunu yapıyorum:

  1. Sınırlı ayrıcalıklara sahip bir veritabanı kullanıcısı oluşturun;
  2. Yalnızca önceki oluşturulan kullanıcı ve süper kullanıcı tarafından erişilebilen bir veritabanı oluşturun (bakım için)
  3. Veritabanını doldurma

Şimdi, PostgreSQL ile aynı şeyi yapmam gerekecek (proje olgunlaşıyor ve MySQL ... tüm ihtiyaçları karşılamıyor).

Tüm veritabanları / şema yedekleri bağımsız olması gerekir: pg_dump her iki şekilde mükemmel çalışır ve aynı sadece bir şema veya bir veritabanına erişmek için yapılandırılabilir kullanıcılar için.

Peki, benden daha deneyimli PostgreSQL kullanıcıları olduğunuzu varsayarsak, durumum için en iyi çözüm nedir ve neden?

$ X şemaları yerine $ x veritabanı kullanıldığında performans farklılıkları olacak mı? Ve gelecekte hangi çözümü korumak daha iyi olacaktır (güvenilirlik)?

Tüm veritabanlarım / şemalarım her zaman aynı yapıya sahip olacak !

Yedekleme sorunu için (pg_dump kullanarak), belki bir veritabanı ve birçok şema kullanmak daha iyidir, tüm şemaları aynı anda boşaltır: kurtarma, bir geliştirme makinesine ana dökümü yüklemek ve daha sonra sadece gerekli şemayı dökmek ve geri yüklemek için oldukça basit olacaktır: ek bir adımdır, ancak tüm şemayı boşaltmak, onları tek tek dökmekten daha hızlı görünür.

GÜNCELLEME 2012

Son iki yılda uygulama yapısı ve tasarımı çok değişti. Hala one db with many schemasyaklaşımı kullanıyorum , ama yine de, benim uygulama her sürümü için bir veritabanı var :

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

Yedeklemeler için, her bir veritabanını düzenli olarak döküyorum ve yedeklemeleri geliştirme sunucusunda taşıyorum.

Ayrıca PITR / WAL yedeğini kullanıyorum, ancak daha önce de söylediğim gibi, muhtemelen tüm veritabanını bir kerede geri yüklemek zorunda kalacağım ... bu yüzden muhtemelen bu yıl reddedilecek (benim durumumda en iyi yaklaşım değil) ).

One-db-many-schema yaklaşımı, uygulama yapısı tamamen değişmiş olsa bile, o zamandan beri benim için çok iyi çalıştı:

Neredeyse unuttum: tüm veritabanlarım / şemalarım her zaman aynı yapıya sahip olacak !

... şimdi, her şemanın kullanıcı veri akışına dinamik olarak tepki veren kendi yapısı vardır.


"Tüm veritabanlarım / şemalarım aynı yapıya sahip olacak!" yani hepsi aynı yapıya mı sahip? Ya da asla?
Osama Al-Maadeed

Üzgünüm, evet, hepsi sonsuza kadar aynı yapıya sahip: birini değiştirirsem hepsini değiştireceğim;)
Strae

1000 müşteriniz varsa, bu 1000 şemayı güncellemeniz gerektiği anlamına mı geliyor?
Joshua Partogi

@ jpartogi: evet, ama sadece tablo yapısını güncellemeliyim, verileri değil.
Strae

Sonunda ne için girdin? Bununla birlikte, bir soru, sorguların vb. Performansının tablo alanları tarafından kontrol edilebilmesine rağmen, çoklu-db'ye karşı çoklu-db'ye eşdeğer performansa neden olan şemalar, WAL günlükleri üzerinde herhangi bir etki ???
Kapil

Yanıtlar:


113

PostgreSQL "şeması" kabaca MySQL "veritabanı" ile aynıdır. PostgreSQL kurulumunda birçok veritabanına sahip olmak sorunlu olabilir; birçok şemaya sahip olmak sorunsuz çalışacaktır. Yani kesinlikle bir veritabanı ve o veritabanı içinde birden fazla şema ile gitmek istersiniz.


33
Bu. Postgres, veritabanlarını sorgulamanıza izin vermez, bu da oldukça can sıkıcı olabilir.
matt b

81
"PostgreSQL kurulumunda birçok veritabanına sahip olmak sorun yaratabilir" - lütfen açıklığa kavuşturun; genel olarak mı yoksa bu özel durumda mı sorunlu ve neden?
akaihola

33
"Bir veritabanında birden fazla şema kullanmak için en yaygın kullanım durumu, her müşterinin kendi şemasına sahip olduğu bir hizmet olarak yazılım uygulaması oluşturmaktır. Bu teknik zorlayıcı gibi görünse de, çok sayıda duruma neden olduğu için buna şiddetle tavsiye ediyoruz. Örneğin, ılımlı sayıda şema (> 50) bile Heroku'nun veritabanı anlık görüntü aracı " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan

16
@NeilMcGuigan: İlginçtir ki, bu kquinn'in (kabul edilen) cevabının tam tersi bir sonuç gibi görünüyor.
karbokasyon

8
Bununla birlikte, birçok şemaya sahip bir veritabanına sahip olmak, bunların tek bir şemasını dökmeyi neredeyse imkansız hale getirecektir. Ben fazla 3000 şemaları ile tek bir postgres veritabanı çalıştırıyorum ve pg_dump sadece bir şema dökümü denerseniz bellek yetersiz hatası ile başarısız. Bunun yerine 3000 veritabanı olsaydı, bunun farklı olup olmayacağını merak ediyorum.
Machisuji

27

Kesinlikle, bir-db-çok-şemaları yaklaşımına gideceğim. Bu, tüm veritabanını dökmeme izin veriyor, ancak pek çok açıdan yalnızca bir tanesini kolayca geri yükleyebiliyor:

  1. Db'yi (tüm şema) dökün, yeni bir db'ye dökümü yükleyin, sadece ihtiyacım olan şemayı dökün ve ana db'ye geri yükleyin.
  2. Şemayı ayrı ayrı dökün (ancak makinenin bu şekilde daha fazla acı çekeceğini düşünüyorum - ve 500 şema gibi bekliyorum!)

Aksi takdirde, googling Bir şemayı (şablon olarak kullanarak) çoğaltmak için otomatik bir prosedür olmadığını gördüm, ancak birçoğu şu yolu gösteriyor:

  1. Şablon şeması oluşturma
  2. Çoğaltmanız gerektiğinde, yeni adla yeniden adlandırın
  3. Boşalt
  4. Yeniden adlandırın
  5. Dökümü geri yükleyin
  6. Sihir yapılır.

Bunu yapmak için Python'da iki satır yazdım; Umarım birilerine yardımcı olabilirler (2 saniyede yazılı kod, üretimde kullanmayın):

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

Ben söyleyebilirim, birden fazla veritabanı ve birden çok şema ile gitmek :)

PostgreSQL'deki şemalar, bunlara aşina olmanız durumunda Oracle'daki paketlere çok benzer. Veritabanları, tüm veri kümeleri arasında ayrım yaparken, şemalar daha çok veri varlıklarına benzer.

Örneğin, "UserManagement", "LongTermStorage" şemaları ile tüm uygulama için tek bir veritabanınız olabilir. "UserManagement" daha sonra "Kullanıcı" tablosunun yanı sıra kullanıcı yönetimi için gereken tüm saklı yordamları, tetikleyicileri, sıraları vb. İçerir.

Veritabanları tüm programlardır, şemalar bileşenlerdir.


4
... ve şemaların içinde 1 veritabanı olacak: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? Mh ... güvenilir bir yol gibi görünmüyor ... ya performans? Peki ya benim uygulama kodu hakkında (php ve python olacak)? pek çok şema ..
Strae

7
@Strae: Bunu şu şekilde okuyorum: her müşterinin kendi veritabanı customer1_database, customer2_database var ve bu veritabanları içinde user_schema, document_schema var.
frankhommers

6

Bir PostgreSQL bağlamında birden çok şema ile bir db kullanmanızı öneririm, çünkü şemalar arasında (örneğin veritabanları arasında değil) UNION ALL. Bu nedenle, şemalar aynı veritabanı içindeki diğer şemalardan yalıtılmazken, bir veritabanı başka bir veritabanından gerçekten tamamen yalıtılır.

Gelecekte bazı nedenlerden ötürü verileri şemalar arasında birleştirmeniz gerekiyorsa, bunu birden fazla şema üzerinden yapmak kolay olacaktır. Birden çok veritabanı ile birden fazla db bağlantısına ihtiyacınız olacak ve her mantıktaki veriyi uygulama mantığı ile "manuel" olarak toplayıp birleştireceksiniz.

İkincisinin bazı durumlarda avantajları vardır, ancak büyük kısmı için tek veritabanı-çoklu şema yaklaşımının daha yararlı olduğunu düşünüyorum.


4

Bunu doğrulayan bir referans bulamasam da, bir dizi şema bir dizi veritabanından daha hafif olmalıdır.

Ancak işleri çok ayrı tutmak istiyorsanız (web uygulamasını tablolarınıza "müşteri" sütunu eklenecek şekilde yeniden düzenlemek yerine) yine de ayrı veritabanları kullanmak isteyebilirsiniz: Geri yüklemeleri daha kolay yapabileceğinizi iddia ediyorum belirli bir müşterinin veritabanını bu şekilde - diğer müşterileri rahatsız etmeden.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.