सरणी के सदस्य पर विदेशी प्रमुख बाधा?


27

मान लीजिए कि मेरे पास नौकरी की भूमिका वाली एक तालिका है:

CREATE TABLE roles
(
  "role" character varying(80) NOT NULL,
  CONSTRAINT "role" PRIMARY KEY (role)
);

मान लीजिए कि मेरे पास एक तालिका है, उपयोगकर्ता हैं, और प्रत्येक पंक्ति (एक विशिष्ट उपयोगकर्ता) में एक मनमानी संख्या हो सकती है:

CREATE TABLE users
(
  username character varying(12) NOT NULL,
  roles character varying(80)[] NOT NULL,
  CONSTRAINT username PRIMARY KEY (username)
);

मुझे शायद यह सुनिश्चित करना चाहिए कि प्रत्येक सदस्य users.roles[]भूमिकाओं में मौजूद है। मुझे ऐसा लगता है कि मैं जो चाहता हूं, वह प्रत्येक सदस्य के लिए एक विदेशी महत्वपूर्ण बाधा users.roles[]है, यदि भूमिकाएं मिलती हैं।

यह पोस्टग्रेज के साथ संभव नहीं लगता है। क्या मैं इसे गलत तरीके से देख रहा हूं? इसे संभालने का सुझाया "सही" तरीका क्या है?

जवाबों:


20

सरणी विदेशी कुंजियों के लिए समर्थन पोस्टग्रेएसक्यूएल 9.3 में प्राप्त करने के लक्ष्य के साथ काम किया गया था, लेकिन इसने प्रदर्शन और विश्वसनीयता समस्याओं के कारण रिलीज के लिए कटौती नहीं की। यह 9.4 के लिए पर काम किया जा रहा है नहीं लगता है।

इस समय, आपको m: n संबंध बनाने के लिए "जॉइन टेबल" का उपयोग करने के सामान्य संबंधपरक दृष्टिकोण से चिपके रहने की आवश्यकता है।

CREATE TABLE user_roles (
   username character varying(12) references users(username),
   "role" character varying(80) references roles("role"),
   PRIMARY KEY(username, "role")
);

मैं इस मामले में सरोगेट कुंजी का उपयोग करने का सुझाव देता हूं , साथ ही, सीधे तालिका में उपयोगकर्ता नाम / भूमिका नामों को संग्रहीत करने के बजाय। पहली बार जब आप किसी उपयोगकर्ता या भूमिका का नाम बदलना चाहते हैं, तो आप खुश होंगे कि आपने सरोगेट कुंजी का उपयोग किया है। बस पर एक uniqueबाधा जगह roles."role"और users.username


3

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

trailer=# create table harvester (id int unique, label text);
CREATE TABLE
trailer=# insert into harvester values (1,'grain'), (2,'cricket');
INSERT 0 2
trailer=# create table donkey (id int, others int references
harvester(id));
CREATE TABLE
trailer=# create unique index donkey_ears on donkey (id, others);
CREATE INDEX
trailer=# create view combine as select id, array_agg(others) as others
from donkey group by id;
CREATE VIEW
trailer=# create rule combine_insert as on insert to combine do instead
(delete from donkey where donkey.id=new.id;insert into donkey select
new.id,unnest(new.others) );
CREATE RULE
trailer=# insert into combine values (1,'{1,2}');INSERT 0 2
trailer=# select * from combine ;
id | others 
----+--------
  1 | {1,2}
(1 row)

trailer=# insert into combine values (1,'{1,2}');
INSERT 0 2
trailer=# select * from combine ;
 id | others 
----+--------
  1 | {1,2}
    (1 row)

trailer=# insert into combine values (2,'{1,2,3}');
ERROR:  insert or update on table "donkey" violates foreign key
constraint "donkey_others_fkey"
DETAIL:  Key (others)=(3) is not present in table "harvester".
trailer=# 

मुझे आशा है कि वह मदद करेंगे। आप इसे थोड़ा अधिक कुशल बना सकते हैं और अपनी आवश्यकताओं के आधार पर अधिक नियम जोड़ सकते हैं।


1

एक बार जब आप उस पैच को प्राप्त कर लेते हैं जो उस कार्यक्षमता को और अधिक यहाँ अनुमति देता है

महज प्रयोग करें: ELEMENT REFERENCES relation( field )

इरादा के लिए:

CREATE TABLE drivers (
   driver_id integer PRIMARY KEY,
   first_name text,
   last_name text,
   ...
);



CREATE TABLE races (
   race_id integer PRIMARY KEY,
   title text,
   race_day DATE,
   ...
   practice1_positions integer[] ELEMENT REFERENCES drivers,
   practice2_positions integer[] ELEMENT REFERENCES drivers,
   practice3_positions integer[] ELEMENT REFERENCES drivers,
   qualifying_positions integer[] ELEMENT REFERENCES drivers,
   final_positions integer[] ELEMENT REFERENCES drivers
);

1
यह बहुत अच्छा लगता है, लेकिन इसे मैन्युअल रूप से पैचिंग इंजन के बिना इस्तेमाल नहीं किया जा सकता है - यह डाउन-वोट का कारण है ...
लैंग्पावेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.