PostgreSQL: Tốt hơn là sử dụng nhiều cơ sở dữ liệu với mỗi lược đồ hoặc một cơ sở dữ liệu có nhiều lược đồ?


147

Sau khi nhận xét này cho một trong những câu hỏi của tôi, tôi nghĩ liệu có tốt hơn khi sử dụng một cơ sở dữ liệu với lược đồ X hoặc ngược lại.

Tình huống của tôi: Tôi đang phát triển một ứng dụng web, khi mọi người đăng ký, tôi tạo (thực tế) một cơ sở dữ liệu (không, đó không phải là mạng xã hội: mọi người phải có quyền truy cập vào dữ liệu của chính mình và không bao giờ thấy dữ liệu của người dùng khác) .

Đó là cách tôi đã sử dụng cho phiên bản trước của ứng dụng của mình (vẫn đang chạy trên MySQL): thông qua API Plesk, cho mỗi lần đăng ký, tôi làm:

  1. Tạo người dùng cơ sở dữ liệu với các đặc quyền hạn chế;
  2. Tạo một cơ sở dữ liệu có thể được truy cập chỉ bởi người dùng đã tạo trước đó và siêu người dùng (để bảo trì)
  3. Tạo cơ sở dữ liệu

Bây giờ, tôi sẽ cần phải làm tương tự với PostgreSQL (dự án đang hoàn thiện và MySQL ... không đáp ứng tất cả các nhu cầu).

Tôi cần phải có tất cả các bản sao lưu cơ sở dữ liệu / lược đồ độc lập: pg_dump hoạt động hoàn hảo theo cả hai cách và giống nhau cho người dùng có thể được cấu hình để truy cập chỉ một lược đồ hoặc một cơ sở dữ liệu.

Vì vậy, giả sử bạn là người dùng PostgreQuery có nhiều kinh nghiệm hơn tôi, bạn nghĩ đâu là giải pháp tốt nhất cho tình huống của tôi, và tại sao?

Sẽ có sự khác biệt về hiệu suất khi sử dụng cơ sở dữ liệu $ x thay vì lược đồ $ x? Và giải pháp nào sẽ tốt hơn để duy trì trong tương lai (độ tin cậy)?

Tất cả các cơ sở dữ liệu / lược đồ của tôi sẽ luôn có cùng cấu trúc!

Đối với vấn đề sao lưu (sử dụng pg_dump), có thể tốt hơn khi sử dụng một cơ sở dữ liệu và nhiều lược đồ, bỏ tất cả các lược đồ cùng một lúc: việc khôi phục sẽ khá đơn giản khi tải kết xuất chính trong máy phát triển, sau đó kết xuất và khôi phục chỉ lược đồ cần thiết: có là một bước bổ sung, nhưng việc loại bỏ tất cả các lược đồ có vẻ nhanh hơn so với việc loại bỏ chúng từng cái một.

CẬP NHẬT 2012

Vâng, cấu trúc và thiết kế ứng dụng đã thay đổi rất nhiều trong hai năm qua. Tôi vẫn đang sử dụng one db with many schemasphương pháp này, nhưng tôi vẫn có một cơ sở dữ liệu cho mỗi phiên bản ứng dụng của mình:

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

Để sao lưu, tôi sẽ bỏ từng cơ sở dữ liệu thường xuyên và sau đó di chuyển các bản sao lưu trên máy chủ phát triển.

Tôi cũng đang sử dụng bản sao lưu PITR / WAL, nhưng như tôi đã nói trước đây, không có khả năng tôi sẽ phải khôi phục tất cả cơ sở dữ liệu cùng một lúc ... vì vậy có lẽ nó sẽ bị loại bỏ trong năm nay (trong tình huống của tôi không phải là cách tiếp cận tốt nhất ).

Cách tiếp cận một-db-many-lược đồ hoạt động rất tốt đối với tôi kể từ bây giờ, ngay cả khi cấu trúc ứng dụng hoàn toàn thay đổi:

Tôi gần như quên mất: tất cả các cơ sở dữ liệu / lược đồ của tôi sẽ luôn có cùng cấu trúc!

... bây giờ, mỗi lược đồ có cấu trúc riêng thay đổi linh hoạt phản ứng với luồng dữ liệu của người dùng.


"tất cả các cơ sở dữ liệu / lược đồ của tôi sẽ có cùng cấu trúc!" bạn có nghĩa là tất cả chúng có cùng cấu trúc? Hoặc không bao giờ?
Osama Al-Maadeed

Xin lỗi, vâng, tất cả chúng đều có cùng cấu trúc: nếu tôi thay đổi một cái, tôi sẽ thay đổi tất cả chúng;)
Strae

Nếu bạn có 1000 khách hàng, điều đó có nghĩa là bạn phải cập nhật 1000 lược đồ?
Joshua Partogi

@jpartogi: có, nhưng tôi phải cập nhật cấu trúc bảng chứ không phải dữ liệu.
Strae

Vì vậy, cuối cùng bạn đã làm gì? Mặc dù, một câu hỏi, mặc dù hiệu năng của các truy vấn, v.v. có thể được kiểm soát bởi các không gian bảng, lược đồ dẫn đến hiệu suất tương đương của đa db so với đa lược đồ, có ảnh hưởng gì đến nhật ký WAL không ???
Kapil

Câu trả lời:


113

Một "lược đồ" PostgreSQL gần giống như "cơ sở dữ liệu" của MySQL. Có nhiều cơ sở dữ liệu trên bản cài đặt PostgreSQL có thể gặp vấn đề; có nhiều lược đồ sẽ làm việc mà không gặp rắc rối. Vì vậy, bạn chắc chắn muốn đi với một cơ sở dữ liệu và nhiều lược đồ trong cơ sở dữ liệu đó.


33
Điều này. Postgres không cho phép bạn truy vấn trên cơ sở dữ liệu, điều này có thể khá khó chịu.
matt b

81
"Có nhiều cơ sở dữ liệu trên bản cài đặt PostgreSQL có thể gặp sự cố" - vui lòng làm rõ; nó có vấn đề nói chung hoặc trong trường hợp cụ thể này, và tại sao?
akaihola

33
"Trường hợp sử dụng phổ biến nhất để sử dụng nhiều lược đồ trong cơ sở dữ liệu là xây dựng ứng dụng phần mềm dưới dạng dịch vụ trong đó mỗi khách hàng có lược đồ riêng. Mặc dù kỹ thuật này có vẻ hấp dẫn, chúng tôi khuyên bạn nên chống lại nó vì nó đã gây ra nhiều trường hợp Ví dụ, ngay cả một số lược đồ vừa phải (> 50) có thể ảnh hưởng nghiêm trọng đến hiệu suất của công cụ chụp nhanh cơ sở dữ liệu của Heroku " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan

16
@NeilMcGuigan: Thật thú vị, đó dường như là kết luận ngược lại với câu trả lời (được chấp nhận) của kquinn.
carbocation

8
Mặc dù có một cơ sở dữ liệu với nhiều lược đồ sẽ khiến cho hầu như không thể kết xuất một lược đồ duy nhất trong số đó. Tôi đang chạy một cơ sở dữ liệu postgres với hơn 3000 lược đồ và pg_dump chỉ bị lỗi với lỗi hết bộ nhớ nếu bạn cố gắng kết xuất một lược đồ duy nhất. Tôi tự hỏi nếu điều này sẽ là bất kỳ khác nhau có I 3000 cơ sở dữ liệu thay thế.
Machisuji

27

Chắc chắn, tôi sẽ đi theo cách tiếp cận một-db-nhiều lược đồ. Điều này cho phép tôi kết xuất tất cả cơ sở dữ liệu, nhưng khôi phục chỉ một cách rất dễ dàng, theo nhiều cách:

  1. Kết xuất db (tất cả các lược đồ), tải kết xuất trong một db mới, kết xuất chỉ lược đồ tôi cần và khôi phục lại trong db chính.
  2. Kết xuất lược đồ một cách riêng biệt, từng cái một (nhưng tôi nghĩ rằng máy sẽ chịu đựng nhiều hơn theo cách này - và tôi đang mong đợi như 500 lược đồ!)

Mặt khác, googling xung quanh tôi đã thấy rằng không có quy trình tự động để sao chép một lược đồ (sử dụng một làm mẫu), nhưng nhiều người đề xuất theo cách này:

  1. Tạo một lược đồ mẫu
  2. Khi cần nhân đôi, đổi tên nó bằng tên mới
  3. Đổ nó
  4. Đổi tên lại
  5. Khôi phục bãi chứa
  6. Phép thuật đã xong.

Tôi đã viết hai hàng bằng Python để làm điều đó; Tôi hy vọng họ có thể giúp ai đó (viết mã trong 2 giây, không sử dụng nó trong sản xuất):

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

Tôi muốn nói, hãy đi với nhiều cơ sở dữ liệu VÀ nhiều lược đồ :)

Các lược đồ trong PostgreSQL rất giống các gói trong Oracle, trong trường hợp bạn quen thuộc với các gói đó. Cơ sở dữ liệu có nghĩa là để phân biệt giữa toàn bộ các bộ dữ liệu, trong khi các lược đồ giống như các thực thể dữ liệu hơn.

Chẳng hạn, bạn có thể có một cơ sở dữ liệu cho toàn bộ ứng dụng với các lược đồ "Quản lý người dùng", "LongTermStorage", v.v. "Quản lý người dùng" sau đó sẽ chứa bảng "Người dùng", cũng như tất cả các thủ tục được lưu trữ, trình kích hoạt, trình tự, v.v ... cần thiết cho việc quản lý người dùng.

Cơ sở dữ liệu là toàn bộ chương trình, lược đồ là các thành phần.


4
... và vì vậy tôi sẽ có 1 cơ sở dữ liệu, bên trong các lược đồ: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_document_schema, $ customer2_document_schema, $ customer3_document_schema? Mh ... có vẻ không phải là một cách đáng tin cậy ... còn hiệu suất thì sao? Và những gì về mã của ứng dụng của tôi (sẽ là php và python)? rất nhiều lược đồ ..
Strae

7
@Strae: Tôi đang đọc cái này như sau: mỗi khách hàng có cơ sở dữ liệu của mình là khách hàng1_database, customer2_database và trong các cơ sở dữ liệu đó bạn có user_schema, Documents_schema.
thân

6

Trong ngữ cảnh PostgreSQL, tôi khuyên bạn nên sử dụng một db với nhiều lược đồ, như bạn có thể (ví dụ) UNION ALL trên các lược đồ, nhưng không phải trên các cơ sở dữ liệu. Vì lý do đó, một cơ sở dữ liệu thực sự được cách ly hoàn toàn với cơ sở dữ liệu khác trong khi các lược đồ không được cách ly với các lược đồ khác trong cùng một cơ sở dữ liệu.

Nếu bạn - vì một số lý do - phải hợp nhất dữ liệu trên các lược đồ trong tương lai, bạn sẽ dễ dàng thực hiện việc này trên nhiều lược đồ. Với nhiều cơ sở dữ liệu, bạn sẽ cần nhiều kết nối db và thu thập và hợp nhất dữ liệu từ mỗi cơ sở dữ liệu "theo cách thủ công" theo logic ứng dụng.

Cái sau có lợi thế trong một số trường hợp, nhưng đối với phần chính tôi nghĩ cách tiếp cận một cơ sở dữ liệu đa cơ sở là hữu ích hơn.


4

Một số lược đồ nên nhẹ hơn một số cơ sở dữ liệu, mặc dù tôi không thể tìm thấy một tài liệu tham khảo xác nhận điều này.

Nhưng nếu bạn thực sự muốn giữ mọi thứ riêng biệt (thay vì cấu trúc lại ứng dụng web để thêm cột "khách hàng" vào bảng của bạn), bạn vẫn có thể muốn sử dụng cơ sở dữ liệu riêng biệt: Tôi khẳng định rằng bạn có thể dễ dàng khôi phục hơn cơ sở dữ liệu của khách hàng cụ thể theo cách này - mà không làm phiền các khách hàng khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.