PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

PostgreSQL के लिए बहु-किरायेदार विकल्प

एक सॉफ्टवेयर सिस्टम में बहु-किरायेदारी को उद्देश्यों के एक सेट को पूरा करने के लिए मानदंडों के एक सेट के अनुसार डेटा का पृथक्करण कहा जाता है। इस पृथक्करण का परिमाण/विस्तार, प्रकृति और अंतिम कार्यान्वयन उन मानदंडों और उद्देश्यों पर निर्भर है। मल्टी-टेनेंसी मूल रूप से डेटा विभाजन का मामला है, लेकिन हम स्पष्ट कारणों से इस शब्द से बचने की कोशिश करेंगे (पोस्टग्रेएसक्यूएल में शब्द का एक बहुत विशिष्ट अर्थ है और आरक्षित है, क्योंकि घोषणात्मक तालिका विभाजन पोस्टग्रेस्क्ल 10 में पेश किया गया था)।

मानदंड हो सकते हैं:

  1. एक महत्वपूर्ण मास्टर टेबल की आईडी के अनुसार, जो कि टैनेंट आईडी का प्रतीक है जो निम्न का प्रतिनिधित्व कर सकता है:
    1. एक बड़े होल्डिंग समूह के भीतर एक कंपनी/संगठन
    2. कंपनी/संगठन के भीतर एक विभाग
    3. एक ही कंपनी/संगठन का एक क्षेत्रीय कार्यालय/शाखा
  2. उपयोगकर्ता के स्थान/आईपी के अनुसार
  3. कंपनी/संगठन के अंदर उपयोगकर्ता की स्थिति के अनुसार

उद्देश्य हो सकते हैं:

  1. भौतिक या आभासी संसाधनों का पृथक्करण
  2. सिस्टम संसाधनों का पृथक्करण
  3. सुरक्षा
  4. कंपनी/संगठन के विभिन्न स्तरों पर प्रबंधन/उपयोगकर्ताओं की सटीकता और सुविधा

नोट एक उद्देश्य को पूरा करके हम नीचे के सभी उद्देश्यों को भी पूरा करते हैं, यानी ए को पूरा करके हम बी, सी और डी भी पूरा करते हैं, बी को पूरा करके हम सी और डी भी पूरा करते हैं, और आगे भी।

यदि हम उद्देश्य A को पूरा करना चाहते हैं तो हम प्रत्येक टैनेंट को उसके स्वयं के भौतिक/आभासी सर्वर के भीतर एक अलग डेटाबेस क्लस्टर के रूप में परिनियोजित करना चुन सकते हैं। यह संसाधनों और सुरक्षा का अधिकतम पृथक्करण देता है लेकिन खराब परिणाम देता है जब हमें पूरे डेटा को एक के रूप में देखने की आवश्यकता होती है, यानी पूरे सिस्टम का समेकित दृश्य।

यदि हम केवल उद्देश्य बी प्राप्त करना चाहते हैं तो हम प्रत्येक किरायेदार को एक ही सर्वर में एक अलग पोस्टग्रेस्क्ल इंस्टेंस के रूप में तैनात कर सकते हैं। यह हमें इस बात पर नियंत्रण देगा कि प्रत्येक उदाहरण के लिए कितनी जगह आवंटित की जाएगी, और सीपीयू/मेम उपयोग पर कुछ नियंत्रण (ओएस के आधार पर)। यह मामला अनिवार्य रूप से A से अलग नहीं है। आधुनिक क्लाउड कंप्यूटिंग युग में, A और B के बीच का अंतर छोटा और छोटा होता जाता है, जिससे A, B की तुलना में संभवतः सबसे पसंदीदा तरीका होगा।

यदि हम उद्देश्य सी, यानी सुरक्षा प्राप्त करना चाहते हैं, तो एक डेटाबेस उदाहरण होना और प्रत्येक किरायेदार को एक अलग डेटाबेस के रूप में तैनात करना पर्याप्त है।

और अंत में यदि हम केवल डेटा के "सॉफ्ट" पृथक्करण की परवाह करते हैं, या दूसरे शब्दों में एक ही सिस्टम के अलग-अलग विचारों की परवाह करते हैं, तो हम इसे केवल एक डेटाबेस इंस्टेंस और एक डेटाबेस द्वारा प्राप्त कर सकते हैं, अंतिम के रूप में नीचे चर्चा की गई तकनीकों की एक बड़ी संख्या का उपयोग करके (और प्रमुख) इस ब्लॉग का विषय। बहु-किरायेदारी की बात करें तो डीबीए के नजरिए से, ए, बी और सी मामलों में काफी समानताएं हैं। ऐसा इसलिए है क्योंकि सभी मामलों में हमारे पास अलग-अलग डेटाबेस होते हैं और उन डेटाबेस को पाटने के लिए, विशेष उपकरणों और तकनीकों का उपयोग किया जाना चाहिए। हालांकि, अगर ऐसा करने की आवश्यकता एनालिटिक्स या बिजनेस इंटेलिजेंस विभागों से आती है, तो किसी ब्रिजिंग की आवश्यकता नहीं हो सकती है, क्योंकि डेटा को उन कार्यों के लिए समर्पित कुछ केंद्रीय सर्वर पर बहुत अच्छी तरह से दोहराया जा सकता है, जिससे ब्रिजिंग अनावश्यक हो जाती है। यदि वास्तव में इस तरह के ब्रिजिंग की आवश्यकता है तो हमें dblink या विदेशी टेबल जैसे टूल का उपयोग करना चाहिए। विदेशी डेटा रैपर के माध्यम से विदेशी टेबल आजकल पसंदीदा तरीका है।

हालांकि, यदि हम विकल्प डी का उपयोग करते हैं, तो समेकन पहले से ही डिफ़ॉल्ट रूप से दिया गया है, इसलिए अब कठिन हिस्सा विपरीत है:अलगाव। इसलिए हम आम तौर पर विभिन्न विकल्पों को दो मुख्य श्रेणियों में वर्गीकृत कर सकते हैं:

  • नरम पृथक्करण
  • कठिन अलगाव

एक ही क्लस्टर में विभिन्न डेटाबेस के माध्यम से कठिन पृथक्करण

मान लीजिए कि हमें कार और नाव किराए पर देने वाले एक काल्पनिक व्यवसाय के लिए एक प्रणाली तैयार करनी है, लेकिन क्योंकि वे दोनों अलग-अलग कानूनों, अलग-अलग नियंत्रणों, ऑडिट द्वारा शासित होते हैं, प्रत्येक कंपनी को अलग-अलग लेखा विभाग बनाए रखना चाहिए और इस प्रकार हम उनके सिस्टम रखना चाहेंगे अलग। इस मामले में हम प्रत्येक कंपनी के लिए एक अलग डेटाबेस चुनना चुनते हैं:rentdb_cars और Rentdb_boats, जिसमें समान स्कीमा होंगे:

# \d customers
                                  Table "public.customers"
   Column    |     Type      | Collation | Nullable |                Default                
-------------+---------------+-----------+----------+---------------------------------------
 id          | integer       |           | not null | nextval('customers_id_seq'::regclass)
 cust_name   | text          |           | not null |
 birth_date  | date          |           |          |
 sex         | character(10) |           |          |
 nationality | text          |           |          |
Indexes:
    "customers_pkey" PRIMARY KEY, btree (id)
Referenced by:
    TABLE "rental" CONSTRAINT "rental_customerid_fkey" FOREIGN KEY (customerid) REFERENCES customers(id)
# \d rental
                              Table "public.rental"
   Column   |  Type   | Collation | Nullable |              Default               
------------+---------+-----------+----------+---------------------------------
 id         | integer |           | not null | nextval('rental_id_seq'::regclass)
 customerid | integer |           | not null |
 vehicleno  | text    |           |          |
 datestart  | date    |           | not null |
 dateend    | date    |           |          |
Indexes:
    "rental_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "rental_customerid_fkey" FOREIGN KEY (customerid) REFERENCES customers(id)

मान लीजिए कि हमारे पास निम्नलिखित किराये हैं। रेंटलdb_cars में:

rentaldb_cars=# select cust.cust_name,rent.vehicleno,rent.datestart FROM rental rent JOIN customers cust on (rent.customerid=cust.id);
    cust_name    | vehicleno | datestart  
-----------------+-----------+------------
 Valentino Rossi | INI 8888  | 2018-08-10
(1 row)

और रेंटलdb_boats में:

rentaldb_boats=# select cust.cust_name,rent.vehicleno,rent.datestart FROM rental rent JOIN customers cust on (rent.customerid=cust.id);
   cust_name    | vehicleno | datestart  
----------------+-----------+------------
 Petter Solberg | INI 9999  | 2018-08-10
(1 row)

अब प्रबंधन प्रणाली के बारे में एक समेकित दृष्टिकोण रखना चाहेगा, उदा। किराये को देखने का एक एकीकृत तरीका। हम इसे एप्लिकेशन के माध्यम से हल कर सकते हैं, लेकिन अगर हम एप्लिकेशन को अपडेट नहीं करना चाहते हैं या स्रोत कोड तक पहुंच नहीं है, तो हम एक केंद्रीय डेटाबेस rentaldb बनाकर इसे हल कर सकते हैं। और विदेशी तालिकाओं का उपयोग करके, निम्नानुसार है:

CREATE EXTENSION IF NOT EXISTS postgres_fdw WITH SCHEMA public;
CREATE SERVER rentaldb_boats_srv FOREIGN DATA WRAPPER postgres_fdw OPTIONS (
    dbname 'rentaldb_boats'
);
CREATE USER MAPPING FOR postgres SERVER rentaldb_boats_srv;
CREATE SERVER rentaldb_cars_srv FOREIGN DATA WRAPPER postgres_fdw OPTIONS (
    dbname 'rentaldb_cars'
);
CREATE USER MAPPING FOR postgres SERVER rentaldb_cars_srv;
CREATE FOREIGN TABLE public.customers_boats (
    id integer NOT NULL,
    cust_name text NOT NULL
)
SERVER rentaldb_boats_srv
OPTIONS (
    table_name 'customers'
);
CREATE FOREIGN TABLE public.customers_cars (
    id integer NOT NULL,
    cust_name text NOT NULL
)
SERVER rentaldb_cars_srv
OPTIONS (
    table_name 'customers'
);
CREATE VIEW public.customers AS
 SELECT 'cars'::character varying(50) AS tenant_db,
    customers_cars.id,
    customers_cars.cust_name
   FROM public.customers_cars
UNION
 SELECT 'boats'::character varying AS tenant_db,
    customers_boats.id,
    customers_boats.cust_name
   FROM public.customers_boats;
CREATE FOREIGN TABLE public.rental_boats (
    id integer NOT NULL,
    customerid integer NOT NULL,
    vehicleno text NOT NULL,
    datestart date NOT NULL
)
SERVER rentaldb_boats_srv
OPTIONS (
    table_name 'rental'
);
CREATE FOREIGN TABLE public.rental_cars (
    id integer NOT NULL,
    customerid integer NOT NULL,
    vehicleno text NOT NULL,
    datestart date NOT NULL
)
SERVER rentaldb_cars_srv
OPTIONS (
    table_name 'rental'
);
CREATE VIEW public.rental AS
 SELECT 'cars'::character varying(50) AS tenant_db,
    rental_cars.id,
    rental_cars.customerid,
    rental_cars.vehicleno,
    rental_cars.datestart
   FROM public.rental_cars
UNION
 SELECT 'boats'::character varying AS tenant_db,
    rental_boats.id,
    rental_boats.customerid,
    rental_boats.vehicleno,
    rental_boats.datestart
   FROM public.rental_boats;

पूरे संगठन में सभी रेंटल और ग्राहकों को देखने के लिए हम बस यह करते हैं:

rentaldb=# select cust.cust_name, rent.* FROM rental rent JOIN customers cust ON (rent.tenant_db=cust.tenant_db AND rent.customerid=cust.id);
    cust_name    | tenant_db | id | customerid | vehicleno | datestart  
-----------------+-----------+----+------------+-----------+------------
 Petter Solberg  | boats     |  1 |          1 | INI 9999  | 2018-08-10
 Valentino Rossi | cars      |  1 |          2 | INI 8888  | 2018-08-10
(2 rows)

यह अच्छा लग रहा है, अलगाव और सुरक्षा की गारंटी है, समेकन हासिल किया गया है, लेकिन फिर भी समस्याएं हैं:

  • ग्राहकों को अलग से बनाए रखा जाना चाहिए, जिसका अर्थ है कि एक ही ग्राहक के दो खाते हो सकते हैं
  • एप्लिकेशन को एक विशेष कॉलम (जैसे कि टेनेंट_डीबी) की धारणा का सम्मान करना चाहिए और इसे हर क्वेरी में जोड़ना चाहिए, जिससे यह त्रुटियों से ग्रस्त हो जाए
  • परिणामस्वरूप दृश्य स्वचालित रूप से अद्यतन करने योग्य नहीं हैं (क्योंकि उनमें UNION शामिल है)

समान डेटाबेस में सॉफ्ट सेपरेशन

जब इस दृष्टिकोण को चुना जाता है तो बॉक्स से बाहर समेकन दिया जाता है और अब कठिन हिस्सा अलगाव है। अलगाव को लागू करने के लिए PostgreSQL हमें ढेर सारे समाधान प्रदान करता है:

  • दृश्य
  • भूमिका स्तर सुरक्षा
  • स्कीमा

विचारों के साथ, एप्लिकेशन को एक क्वेरी करने योग्य सेटिंग सेट करनी चाहिए जैसे कि application_name, हम मुख्य तालिका को एक दृश्य के पीछे छिपाते हैं, और फिर इस मुख्य तालिका के किसी भी बच्चे (जैसे FK निर्भरता में) तालिकाओं पर प्रत्येक क्वेरी में, यदि कोई हो, के साथ जुड़ते हैं यह दृश्य। हम इसे निम्नलिखित उदाहरण में एक डेटाबेस में देखेंगे जिसे हम Rentdb_one कहते हैं। हम मुख्य तालिका में टेनेंट कंपनी की पहचान एम्बेड करते हैं:

rentaldb_one=# \d rental_one
                                   Table "public.rental_one"
   Column   |         Type          | Collation | Nullable |              Default               
------------+-----------------------+-----------+----------+------------------------------------
 company    | character varying(50) |           | not null |
 id         | integer               |           | not null | nextval('rental_id_seq'::regclass)
 customerid | integer               |           | not null |
 vehicleno  | text                  |           |          |
 datestart  | date                  |           | not null |
 dateend    | date                  |           |          |
Indexes:
    "rental_pkey" PRIMARY KEY, btree (id)
Check constraints:
    "rental_company_check" CHECK (company::text = ANY (ARRAY['cars'::character varying, 'boats'::character varying]::text[]))
Foreign-key constraints:
    "rental_customerid_fkey" FOREIGN KEY (customerid) REFERENCES customers(id)
आज श्वेतपत्र डाउनलोड करें क्लस्टरकंट्रोल के साथ पोस्टग्रेएसक्यूएल प्रबंधन और स्वचालन इस बारे में जानें कि पोस्टग्रेएसक्यूएल को तैनात करने, मॉनिटर करने, प्रबंधित करने और स्केल करने के लिए आपको क्या जानना चाहिए। श्वेतपत्र डाउनलोड करें

टेबल ग्राहकों की स्कीमा वही रहती है। आइए डेटाबेस की वर्तमान सामग्री देखें:

rentaldb_one=# select * from customers;
 id |    cust_name    | birth_date | sex | nationality
----+-----------------+------------+-----+-------------
  2 | Valentino Rossi | 1979-02-16 |     |
  1 | Petter Solberg  | 1974-11-18 |     |
(2 rows)
rentaldb_one=# select * from rental_one ;
 company | id | customerid | vehicleno | datestart  | dateend
---------+----+------------+-----------+------------+---------
 cars    |  1 |          2 | INI 8888  | 2018-08-10 |
 boats   |  2 |          1 | INI 9999  | 2018-08-10 |
(2 rows)

हम इसे नए दृश्य के पीछे छिपाने के लिए नए नाम रेंटल_ऑन का उपयोग करते हैं जिसमें तालिका का वही नाम होगा जिसकी एप्लिकेशन अपेक्षा करता है:रेंटल। एप्लिकेशन को टैनेंट को दर्शाने के लिए एप्लिकेशन नाम सेट करने की आवश्यकता होगी। तो इस उदाहरण में हमारे पास आवेदन के तीन उदाहरण होंगे, एक कारों के लिए, एक नावों के लिए और एक शीर्ष प्रबंधन के लिए। एप्लिकेशन का नाम इस प्रकार सेट किया गया है:

rentaldb_one=# set application_name to 'cars';

अब हम दृश्य बनाते हैं:

create or replace view rental as select company as "tenant_db",id,customerid,vehicleno,datestart,dateend from rental_one where (company = current_setting('application_name') OR current_setting('application_name')='all');

नोट:हम एक ही कॉलम और टेबल/व्यू नामों को यथासंभव रखते हैं, बहु-किरायेदार समाधानों में मुख्य बिंदु चीजों को एप्लिकेशन साइड में समान रखना है, और परिवर्तनों को न्यूनतम और प्रबंधनीय होना है।

आइए कुछ चयन करें:

Rentdb_one=# application_name को 'cars' पर सेट करें;

rentaldb_one=# set application_name to 'cars';
SET
rentaldb_one=# select * from rental;
 tenant_db | id | customerid | vehicleno | datestart  | dateend
-----------+----+------------+-----------+------------+---------
 cars      |  1 |          2 | INI 8888  | 2018-08-10 |
(1 row)
rentaldb_one=# set application_name to 'boats';
SET
rentaldb_one=# select * from rental;
 tenant_db | id | customerid | vehicleno | datestart  | dateend
-----------+----+------------+-----------+------------+---------
 boats     |  2 |          1 | INI 9999  | 2018-08-10 |
(1 row)
rentaldb_one=# set application_name to 'all';
SET
rentaldb_one=# select * from rental;
 tenant_db | id | customerid | vehicleno | datestart  | dateend
-----------+----+------------+-----------+------------+---------
 cars      |  1 |          2 | INI 8888  | 2018-08-10 |
 boats     |  2 |          1 | INI 9999  | 2018-08-10 |
(2 rows)

एप्लिकेशन का तीसरा उदाहरण जिसे एप्लिकेशन का नाम "सभी" पर सेट करना होगा, पूरे डेटाबेस को देखने के लिए शीर्ष प्रबंधन द्वारा उपयोग के लिए अभिप्रेत है।

एक अधिक मजबूत समाधान, सुरक्षा के लिहाज से, आरएलएस (पंक्ति स्तर की सुरक्षा) पर आधारित हो सकता है। पहले हम तालिका का नाम पुनर्स्थापित करते हैं, याद रखें कि हम एप्लिकेशन को परेशान नहीं करना चाहते हैं:

rentaldb_one=# alter view rental rename to rental_view;
rentaldb_one=# alter table rental_one rename TO rental;

पहले हम प्रत्येक कंपनी (नाव, कार) के लिए उपयोगकर्ताओं के दो समूह बनाते हैं, जिन्हें डेटा का अपना सबसेट देखना होगा:

rentaldb_one=# create role cars_employees;
rentaldb_one=# create role boats_employees;

अब हम प्रत्येक समूह के लिए सुरक्षा नीतियां बनाते हैं:

rentaldb_one=# create policy boats_plcy ON rental to boats_employees USING(company='boats');
rentaldb_one=# create policy cars_plcy ON rental to cars_employees USING(company='cars');

दो भूमिकाओं के लिए आवश्यक अनुदान देने के बाद:

rentaldb_one=# grant ALL on SCHEMA public to boats_employees ;
rentaldb_one=# grant ALL on SCHEMA public to cars_employees ;
rentaldb_one=# grant ALL on ALL tables in schema public TO cars_employees ;
rentaldb_one=# grant ALL on ALL tables in schema public TO boats_employees ;

हम प्रत्येक भूमिका में एक उपयोगकर्ता बनाते हैं

rentaldb_one=# create user boats_user password 'boats_user' IN ROLE boats_employees;
rentaldb_one=# create user cars_user password 'cars_user' IN ROLE cars_employees;

और परीक्षण करें:

[email protected]:~> psql -U cars_user rentaldb_one
Password for user cars_user:
psql (10.5)
Type "help" for help.

rentaldb_one=> select * from rental;
 company | id | customerid | vehicleno | datestart  | dateend
---------+----+------------+-----------+------------+---------
 cars    |  1 |          2 | INI 8888  | 2018-08-10 |
(1 row)

rentaldb_one=> \q
[email protected]:~> psql -U boats_user rentaldb_one
Password for user boats_user:
psql (10.5)
Type "help" for help.

rentaldb_one=> select * from rental;
 company | id | customerid | vehicleno | datestart  | dateend
---------+----+------------+-----------+------------+---------
 boats   |  2 |          1 | INI 9999  | 2018-08-10 |
(1 row)

rentaldb_one=>

इस दृष्टिकोण के साथ अच्छी बात यह है कि हमें आवेदन के कई उदाहरणों की आवश्यकता नहीं है। सभी अलगाव उपयोगकर्ता की भूमिकाओं के आधार पर डेटाबेस स्तर पर किया जाता है। इसलिए शीर्ष प्रबंधन में एक उपयोगकर्ता बनाने के लिए हमें केवल इस उपयोगकर्ता को दोनों भूमिकाएँ प्रदान करने की आवश्यकता है:

rentaldb_one=# create user all_user password 'all_user' IN ROLE boats_employees, cars_employees;
[email protected]:~> psql -U all_user rentaldb_one
Password for user all_user:
psql (10.5)
Type "help" for help.

rentaldb_one=> select * from rental;
 company | id | customerid | vehicleno | datestart  | dateend
---------+----+------------+-----------+------------+---------
 cars    |  1 |          2 | INI 8888  | 2018-08-10 |
 boats   |  2 |          1 | INI 9999  | 2018-08-10 |
(2 rows)

उन दो समाधानों को देखते हुए हम देखते हैं कि दृश्य समाधान के लिए मूल तालिका नाम को बदलने की आवश्यकता होती है, जो कि बहुत ही दखल देने वाला हो सकता है, जिसमें हमें गैर-मल्टीटेनेंट समाधान में ठीक उसी स्कीमा को चलाने की आवश्यकता हो सकती है, या ऐसे ऐप के साथ जिसे <के बारे में पता नहीं है। em>application_name , जबकि दूसरा समाधान लोगों को विशिष्ट किरायेदारों से बांधता है। क्या होगा यदि वही व्यक्ति काम करता है उदा। नावों के किराएदार पर सुबह और कार किराएदार पर दोपहर में? हम स्कीमा के आधार पर एक तीसरा समाधान देखेंगे, जो मेरी राय में सबसे बहुमुखी है, और ऊपर वर्णित दो समाधानों में से किसी भी चेतावनी से ग्रस्त नहीं है। यह एप्लिकेशन को किरायेदार-अज्ञेय तरीके से चलाने की अनुमति देता है, और सिस्टम इंजीनियरों को जरूरत पड़ने पर किरायेदारों को जोड़ने की अनुमति देता है। हम पहले की तरह ही डिज़ाइन रखेंगे, उसी परीक्षण डेटा के साथ (हम Rentdb_one उदाहरण डीबी पर काम करते रहेंगे)। यहां विचार मुख्य तालिका के सामने एक डेटाबेस ऑब्जेक्ट के रूप में एक अलग स्कीमा में एक परत जोड़ने का है जो search_path . में काफी जल्दी होगा उस विशिष्ट किरायेदार के लिए। search_path सेट किया जा सकता है (आदर्श रूप से एक विशेष फ़ंक्शन के माध्यम से, जो अधिक विकल्प देता है) एप्लिकेशन सर्वर परत पर डेटा स्रोत के कनेक्शन कॉन्फ़िगरेशन में (इसलिए एप्लिकेशन कोड के बाहर)। पहले हम दो स्कीमा बनाते हैं:

rentaldb_one=# create schema cars;
rentaldb_one=# create schema boats;

फिर हम प्रत्येक स्कीमा में डेटाबेस ऑब्जेक्ट (विचार) बनाते हैं:

CREATE OR REPLACE VIEW boats.rental AS
 SELECT rental.company,
    rental.id,
    rental.customerid,
    rental.vehicleno,
    rental.datestart,
    rental.dateend
   FROM public.rental
  WHERE rental.company::text = 'boats';
CREATE OR REPLACE VIEW cars.rental AS
 SELECT rental.company,
    rental.id,
    rental.customerid,
    rental.vehicleno,
    rental.datestart,
    rental.dateend
   FROM public.rental
  WHERE rental.company::text = 'cars';

अगला चरण प्रत्येक टैनेंट में खोज पथ को निम्नानुसार सेट करना है:

  • नाव किराएदार के लिए:

    set search_path TO 'boats, "$user", public';
  • कार किराएदार के लिए:

    set search_path TO 'cars, "$user", public';
  • शीर्ष एमजीएमटी टैनेंट के लिए इसे डिफ़ॉल्ट रूप से छोड़ दें

आइए परीक्षण करें:

rentaldb_one=# select * from rental;
 company | id | customerid | vehicleno | datestart  | dateend
---------+----+------------+-----------+------------+---------
 cars    |  1 |          2 | INI 8888  | 2018-08-10 |
 boats   |  2 |          1 | INI 9999  | 2018-08-10 |
(2 rows)

rentaldb_one=# set search_path TO 'boats, "$user", public';
SET
rentaldb_one=# select * from rental;
 company | id | customerid | vehicleno | datestart  | dateend
---------+----+------------+-----------+------------+---------
 boats   |  2 |          1 | INI 9999  | 2018-08-10 |
(1 row)

rentaldb_one=# set search_path TO 'cars, "$user", public';
SET
rentaldb_one=# select * from rental;
 company | id | customerid | vehicleno | datestart  | dateend
---------+----+------------+-----------+------------+---------
 cars    |  1 |          2 | INI 8888  | 2018-08-10 |
(1 row)
PostgreSQL के लिए संबंधित संसाधन PostgreSQL PostgreSQL ट्रिगर और संग्रहीत फ़ंक्शन मूल बातें ट्यूनिंग इनपुट/आउटपुट (I/O) संचालन के लिए ClusterControl

search_path सेट करने के बजाय हम अधिक जटिल तर्क को संभालने के लिए एक अधिक जटिल फ़ंक्शन लिख सकते हैं और इसे हमारे एप्लिकेशन या कनेक्शन पूलर के कनेक्शन कॉन्फ़िगरेशन में कॉल कर सकते हैं।

ऊपर के उदाहरण में हमने सार्वजनिक स्कीमा (public.rental) पर रहने वाली एक ही केंद्रीय तालिका और प्रत्येक किरायेदार के लिए दो अतिरिक्त विचारों का उपयोग किया है, इस भाग्यशाली तथ्य का उपयोग करते हुए कि वे दो विचार सरल हैं और इसलिए लिखने योग्य हैं। विचारों के बजाय हम सार्वजनिक तालिका से विरासत में प्राप्त प्रत्येक किरायेदार के लिए एक चाइल्ड टेबल बनाकर, इनहेरिटेंस का उपयोग कर सकते हैं। यह टेबल इनहेरिटेंस के लिए एक बढ़िया मेल है, जो PostgreSQL की एक अनूठी विशेषता है। शीर्ष तालिका को सम्मिलित करने की अनुमति न देने के लिए नियमों के साथ कॉन्फ़िगर किया जा सकता है। इनहेरिटेंस सॉल्यूशन में बच्चों की टेबल को पॉप्युलेट करने और पैरेंट टेबल में इंसर्ट एक्सेस को रोकने के लिए एक रूपांतरण की आवश्यकता होगी, इसलिए यह विचारों के मामले में उतना आसान नहीं है, जो डिजाइन पर न्यूनतम प्रभाव के साथ काम करता है। हम इसे कैसे करें इस पर एक विशेष ब्लॉग लिख सकते हैं।

और भी अधिक विकल्प देने के लिए उपरोक्त तीन दृष्टिकोणों को जोड़ा जा सकता है।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. कैसे Atanh () PostgreSQL में काम करता है

  2. PostgreSQL स्थापना के बाइनरी प्रारूप पर लिखने योग्य mongo_fdw एक्सटेंशन को संकलित करना।

  3. PostgreSQL में एक फ़ंक्शन से वापसी तालिका प्रकार

  4. सुपरयूजर भूमिका के बिना एक्सटेंशन नहीं बना सकते

  5. OmniDB के साथ PostgreSQL 12 के प्रदर्शन की निगरानी कैसे करें - भाग 1