PostgreSQL: มันจะดีกว่าถ้าใช้หลายฐานข้อมูลกับหนึ่ง schema หรือฐานข้อมูลหนึ่งที่มีหลาย schema?


147

หลังจากความคิดเห็นนี้กับหนึ่งในคำถามของฉันฉันคิดว่ามันจะดีกว่าการใช้ฐานข้อมูลเดียวกับ X schemas หรือในทางกลับกัน

สถานการณ์ของฉัน: ฉันกำลังพัฒนาเว็บแอปพลิเคชั่นที่เมื่อผู้คนลงทะเบียนฉันสร้าง (จริง ๆ ) ฐานข้อมูล (ไม่มันไม่ใช่เครือข่ายโซเชียล: ทุกคนต้องเข้าถึงข้อมูลของตัวเองและไม่เห็นข้อมูลของผู้ใช้คนอื่น) .

นั่นคือวิธีที่ฉันใช้สำหรับเวอร์ชันก่อนหน้าของแอปพลิเคชันของฉัน (ที่ยังคงทำงานบน MySQL): ผ่าน Plesk API สำหรับการลงทะเบียนทุกครั้งฉันทำได้

  1. สร้างผู้ใช้ฐานข้อมูลที่มีสิทธิ์ จำกัด ;
  2. สร้างฐานข้อมูลที่สามารถเข้าถึงได้โดยผู้ใช้ที่สร้างไว้ก่อนหน้าและ superuser (สำหรับการบำรุงรักษา)
  3. เติมฐานข้อมูล

ตอนนี้ฉันจะต้องทำเช่นเดียวกันกับ PostgreSQL (โครงการกำลังจะเติบโตและ MySQL ... ไม่ตอบสนองทุกความต้องการ)

ฉันต้องมีการสำรองฐานข้อมูล / สกีมาทั้งหมด: pg_dump ทำงานได้อย่างสมบูรณ์แบบทั้งสองวิธีและเหมือนกันสำหรับผู้ใช้ที่สามารถกำหนดค่าให้เข้าถึงสคีมาเดียวหรือฐานข้อมูลเดียว

ดังนั้นสมมติว่าคุณเป็นผู้ใช้ PostgreSQL ที่มีประสบการณ์มากกว่าฉันคุณคิดว่าอะไรคือทางออกที่ดีที่สุดสำหรับสถานการณ์ของฉันและทำไม

จะมีความแตกต่างด้านประสิทธิภาพโดยใช้ฐานข้อมูล $ x แทนที่จะเป็น $ x schemas หรือไม่ และจะแก้ปัญหาอะไรได้ดีในอนาคต (ความน่าเชื่อถือ)

ฐานข้อมูล / สกีมาทั้งหมดของฉันจะมีโครงสร้างเหมือนกันเสมอ !

สำหรับปัญหาการสำรองข้อมูล (โดยใช้ pg_dump) อาจดีกว่าการใช้ฐานข้อมูลเดียวและสกีมาจำนวนมากทิ้งสกีมาทั้งหมดในครั้งเดียว: การกู้คืนจะเป็นการโหลดดัมพ์หลักในเครื่องพัฒนาอย่างง่ายและจากนั้นถ่ายโอนข้อมูลและกู้คืน เป็นอีกขั้นตอนหนึ่ง แต่การทิ้งสคีมาทั้งหมดดูเหมือนจะเร็วกว่าการทิ้งข้อมูลทีละอย่าง

อัพเดท 2012

โครงสร้างแอปพลิเคชันและการออกแบบเปลี่ยนแปลงไปมากในช่วงสองปีที่ผ่านมา ฉันยังคงใช้one db with many schemasวิธีการนี้อยู่ แต่ฉันยังมีฐานข้อมูลหนึ่งฐานสำหรับแอปพลิเคชันแต่ละเวอร์ชัน :

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

สำหรับการสำรองข้อมูลฉันจะทิ้งแต่ละฐานข้อมูลเป็นประจำแล้วย้ายการสำรองข้อมูลบนเซิร์ฟเวอร์การพัฒนา

ฉันยังใช้การสำรองข้อมูล PITR / WAL แต่อย่างที่ฉันบอกไว้ก่อนหน้านี้ไม่น่าที่ฉันจะต้องกู้คืนฐานข้อมูลทั้งหมดในครั้งเดียว ... ดังนั้นจึงอาจมีการยกเลิกในปีนี้ (ในสถานการณ์ของฉันไม่ใช่วิธีที่ดีที่สุด )

one-db-many-schema วิธีการทำงานได้ดีมากสำหรับฉันตั้งแต่ตอนนี้แม้ว่าโครงสร้างแอปพลิเคชันจะเปลี่ยนไปโดยสิ้นเชิง:

ฉันเกือบลืม: ฐานข้อมูล / สกีมาทั้งหมดของฉันจะมีโครงสร้างเดียวกันเสมอ !

... ตอนนี้สกีมาทุกตัวมีโครงสร้างของตนเองที่เปลี่ยนแปลงการตอบสนองต่อการไหลของข้อมูลของผู้ใช้แบบไดนามิก


"ฐานข้อมูล / สกีมาทั้งหมดของฉันจะมีโครงสร้างเดียวกัน!" คุณหมายถึงพวกเขาทั้งหมดมีโครงสร้างเดียวกันหรือไม่ หรือไม่เคย?
Osama Al-Maadeed

ขออภัยใช่พวกเขาทุกคนมีโครงสร้างเดียวกันตลอดไป: ถ้าฉันเปลี่ยนหนึ่งฉันจะเปลี่ยนพวกเขาทั้งหมด;)
20221

หากคุณมีลูกค้า 1,000 รายนั่นหมายความว่าคุณต้องอัปเดต 1,000 สคีมาหรือไม่
Joshua Partogi

@ jpartogi: ใช่ แต่ฉันต้องอัปเดตเฉพาะโครงสร้างตารางไม่ใช่ข้อมูล
Strae

ดังนั้นสิ่งที่คุณไปในที่สุด? แม้ว่าคำถามหนึ่งถึงแม้ว่าประสิทธิภาพของเคียวรี ฯลฯ สามารถควบคุมได้โดยใช้พื้นที่ตาราง แต่สกีมาส่งผลให้ประสิทธิภาพของ multi-db เทียบกับหลายสคีมามีผลเทียบเท่ากับบันทึก WAL ใด ๆ
Kapil

คำตอบ:


113

PostgreSQL "schema" นั้นเหมือนกับฐานข้อมูล MySQL "โดยประมาณ การมีฐานข้อมูลจำนวนมากในการติดตั้ง PostgreSQL อาจทำให้เกิดปัญหาได้ การมีสกีมาจำนวนมากจะทำงานได้อย่างไม่มีปัญหา ดังนั้นคุณต้องการไปกับฐานข้อมูลเดียวและหลาย schema ภายในฐานข้อมูลนั้น


33
นี้. Postgres ไม่อนุญาตให้คุณสืบค้นข้ามฐานข้อมูลซึ่งอาจน่ารำคาญ
matt b

81
"การมีฐานข้อมูลจำนวนมากในการติดตั้ง PostgreSQL อาจทำให้เกิดปัญหา" - โปรดอธิบาย; เป็นปัญหาทั่วไปหรือในกรณีนี้โดยเฉพาะและทำไม?
akaihola

33
"กรณีการใช้งานที่พบบ่อยที่สุดสำหรับการใช้หลายสคีมาในฐานข้อมูลคือการสร้างแอปพลิเคชันซอฟต์แวร์เป็นบริการที่ลูกค้าแต่ละรายมีสคีมาของตัวเองในขณะที่เทคนิคนี้ดูน่าสนใจเราขอแนะนำอย่างยิ่ง ปัญหาการดำเนินงานตัวอย่างเช่นแม้แต่ schemas จำนวนปานกลาง (> 50) อาจส่งผลกระทบอย่างรุนแรงต่อประสิทธิภาพการทำงานของเครื่องมือสแนปชอตฐานข้อมูลของ Heroku " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan

16
@NeilMcGuigan: น่าสนใจว่านั่นเป็นข้อสรุปที่ตรงกันข้ามกับคำตอบ (ยอมรับ) ของ kquinn
carbocation

8
แม้ว่าการมีฐานข้อมูลเดียวที่มีสกีมาจำนวนมากจะทำให้มันเป็นไปไม่ได้เลยที่จะทิ้งดัชคีเดียวของฐานข้อมูลเหล่านั้น ฉันใช้ฐานข้อมูล postgres เดียวที่มีสกีมามากกว่า 3,000 รายการและ pg_dump เพิ่งล้มเหลวโดยมีข้อผิดพลาดหน่วยความจำไม่เพียงพอหากคุณพยายามที่จะถ่ายโอนสกีมาเดียว ฉันสงสัยว่ามันจะแตกต่างกันหรือไม่หากฉันมีฐานข้อมูล 3000 แทน
Machisuji

27

แน่นอนฉันจะไปสำหรับหนึ่ง - db - many - schemas วิธี สิ่งนี้ช่วยให้ฉันสามารถถ่ายโอนฐานข้อมูลทั้งหมด แต่คืนค่าได้อย่างง่ายดายเพียงหลายวิธี:

  1. ดัมพ์ db (schema ทั้งหมด), โหลดดัมพ์ใน db ใหม่, ดัมพ์เฉพาะ schema ที่ฉันต้องการ, และกู้คืนกลับมาใน db หลัก
  2. ทิ้ง schema แยกกันทีละตัว (แต่ฉันคิดว่าเครื่องจะต้องทนทุกข์ทรมานมากขึ้นด้วยวิธีนี้ - และฉันคาดหวังว่าจะมี 500 schema!)

ไม่เช่นนั้นฉันก็เห็นว่าไม่มีขั้นตอนอัตโนมัติในการทำซ้ำสคีมา (ใช้เป็นเทมเพลต) แต่มีหลายวิธีที่แนะนำ:

  1. สร้างเทมเพลต - สคีมา
  2. เมื่อต้องการทำซ้ำให้เปลี่ยนชื่อเป็นชื่อใหม่
  3. ทิ้งมัน
  4. เปลี่ยนชื่อมันกลับ
  5. คืนค่าดัมพ์
  6. เวทย์มนตร์เสร็จแล้ว

ฉันเขียนสองแถวใน Python เพื่อทำสิ่งนั้น ฉันหวังว่าพวกเขาสามารถช่วยเหลือใครบางคน (ใน 2 วินาที - เขียนโค้ดไม่ใช้ในการผลิต):

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

ฉันจะบอกว่าไปกับฐานข้อมูลหลาย ๆ และหลาย schema :)

Schemas ใน PostgreSQL นั้นคล้ายกับแพ็คเกจใน Oracle ในกรณีที่คุณคุ้นเคย ฐานข้อมูลมีจุดมุ่งหมายเพื่อแยกความแตกต่างระหว่างชุดข้อมูลทั้งหมดในขณะที่ schema นั้นเป็นเหมือนเอนทิตีข้อมูล

ตัวอย่างเช่นคุณสามารถมีฐานข้อมูลเดียวสำหรับทั้งแอปพลิเคชันที่มีสกีมา "UserManagement", "LongTermStorage" และอื่น ๆ "การจัดการผู้ใช้" จะมีตาราง "ผู้ใช้" เช่นเดียวกับขั้นตอนการจัดเก็บทริกเกอร์ลำดับ ฯลฯ ที่จำเป็นสำหรับการจัดการผู้ใช้

ฐานข้อมูลเป็นโปรแกรมทั้งหมด schema เป็นส่วนประกอบ


4
... ดังนั้นฉันจะมี 1 ฐานข้อมูลโดยมีภายใน schemas: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? อืม ... ดูเหมือนจะไม่น่าเชื่อถือเลย ... แล้วเรื่องประสิทธิภาพล่ะ? และรหัสเกี่ยวกับแอปพลิเคชันของฉัน (จะเป็น php และ python) สกีมาจำนวนมากดังนั้น ..
Straßeการเดินทาง

7
@Strae: ฉันกำลังอ่านสิ่งนี้เป็น: ลูกค้าแต่ละรายมีฐานข้อมูล customer1_database, customer2_database และภายในฐานข้อมูลเหล่านั้นที่คุณมี user_schema, documents_schema
frankhommers

6

ในบริบท PostgreSQL ฉันแนะนำให้ใช้หนึ่ง db ที่มีหลาย schema ที่คุณสามารถ (เช่น) UNION ALL ข้าม schema ทั้งหมด แต่ไม่ควรข้ามฐานข้อมูล ด้วยเหตุนี้ฐานข้อมูลจึงได้รับการหุ้มฉนวนอย่างสมบูรณ์จากฐานข้อมูลอื่นในขณะที่ schema นั้นไม่ได้ถูกหุ้มด้วย schema อื่น ๆ ในฐานข้อมูลเดียวกัน

หากคุณ - ด้วยเหตุผลบางอย่าง - ต้องรวบรวมข้อมูลข้ามสกีมาในอนาคตมันจะง่ายกว่าการทำแบบนี้กับ schema หลาย ๆ ตัว ด้วยหลายฐานข้อมูลคุณจะต้องเชื่อมต่อฐานข้อมูลหลาย ๆ แห่งและรวบรวมและรวมข้อมูลจากแต่ละฐานข้อมูล "ด้วยตนเอง" โดยตรรกะของแอปพลิเคชัน

หลังมีข้อได้เปรียบในบางกรณี แต่สำหรับส่วนใหญ่ฉันคิดว่าวิธีการหนึ่งฐานข้อมูลแบบหลายสกีมามีประโยชน์มากกว่า


4

สกีมาจำนวนหนึ่งควรเบากว่าฐานข้อมูลจำนวนมากถึงแม้ว่าฉันไม่สามารถหาข้อมูลอ้างอิงที่ยืนยันสิ่งนี้ได้

แต่ถ้าคุณต้องการแยกสิ่งต่าง ๆ ออกจากกันจริงๆ (แทนที่จะทำการเปลี่ยนเว็บแอปพลิเคชันใหม่เพื่อให้มีการเพิ่มคอลัมน์ "ลูกค้า" ลงในตารางของคุณ) คุณยังอาจต้องการใช้ฐานข้อมูลแยกต่างหาก: ฉันยืนยันว่าคุณสามารถทำการกู้คืนได้ง่ายขึ้น ฐานข้อมูลของลูกค้าโดยเฉพาะด้วยวิธีนี้ - โดยไม่รบกวนลูกค้ารายอื่น

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.