2012-11-06 34 views
7

एक बिक्री के संबंध में, एक उपयोगकर्ता से दूसरी प्रतिक्रिया के लिए, हमारे पास एक अनूठी बाधा वाली एक तालिका है।मुलायम हटाए गए पंक्तियों के साथ अनन्य बाधा

ALTER TABLE feedback 
ADD CONSTRAINT unique_user_subject_and_sale 
UNIQUE (user_id, subject_id, sale_id) 

यह सुनिश्चित करता है कि हमें गलती से प्रतिक्रिया की डुप्लिकेट पंक्तियां न मिलें।

वर्तमान में हम कभी-कभी त्रुटि में छोड़े गए फ़ीडबैक को कड़ी मेहनत करते हैं और उपयोगकर्ता को इसे फिर से छोड़ देते हैं। हम नरम नष्ट करने के लिए बदलना चाहते हैं:

ALTER TABLE feedback 
ADD COLUMN deleted_at timestamptz 

deleted_at IS NOT NULL हैं, पर विचार प्रतिक्रिया नष्ट कर दिया, हालांकि हम अभी भी हमारे डीबी में लेखापरीक्षा निशान है (और शायद यह साइट व्यवस्थापक के लिए बाहर ghosted दिखाई देगा)।

हम इस तरह की सॉफ्ट-डिलीट का उपयोग करते समय अपनी अनूठी बाधा कैसे रख सकते हैं? क्या यह अधिक सामान्य CHECK() बाधा का उपयोग किए बिना एक समग्र जांच करता है (मैंने कभी इस तरह की जांच बाधा का उपयोग करने की कोशिश नहीं की है) का उपयोग किए बिना संभव है।

ऐसा लगता है कि मुझे बाधा के लिए एक WHERE खंड जोड़ने की आवश्यकता है।

उत्तर

14

आपका अद्वितीय सूचकांक कर सकते हैं, बाद में पता संपादित ।

CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_null 
ON feedback(user_id, subject_id, sale_id) 
WHERE deleted_at IS NULL 

आपकी अनूठी अनुक्रमणिका में कम से कम दो दुष्प्रभाव हैं जो आपको कुछ परेशानी का कारण बन सकते हैं।

  1. अन्य तालिकाओं में, आप एक विदेशी कुंजी बाधा सेट नहीं कर सकते जो "प्रतिक्रिया" संदर्भित करता है। एक विदेशी कुंजी संदर्भ के लिए कॉलम के कुछ संयोजन को primary key या unique के रूप में घोषित करने की आवश्यकता होती है।
  2. आपकी अनूठी अनुक्रमणिका कई पंक्तियों को अनुमति देती है जो "हटाए गए" टाइमस्टैम्प में केवल भिन्न होती हैं। तो यह संभव है जो नीचे दिए गए उदाहरण की तरह दिखने वाली पंक्तियों के साथ समाप्त होता है। चाहे यह एक समस्या है आवेदन-निर्भर है।

उदाहरण

user_id subject_id sale_id deleted_at 
-- 
1  1   1  2012-01-01 08:00:01.33 
1  1   1  2012-01-01 08:00:01.34 
1  1   1  2012-01-01 08:00:01.35 

PostgreSQL दस्तावेजों एक आंशिक सूचकांक के रूप में सूचकांक इस तरह, आप इसे कुछ समय गूगल की जरूरत है चाहिए। अन्य प्लेटफ़ॉर्म इसके लिए अलग-अलग शर्तों का उपयोग करते हैं - फ़िल्टर किए गए इंडेक्स एक है। आप आंशिक अनुक्रमणिका की एक जोड़ी के साथ समस्याओं को कुछ हद तक सीमित कर सकते हैं।

CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_null 
ON feedback(user_id, subject_id, sale_id) 
WHERE deleted_at IS NULL 

CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale_not_null 
ON feedback(user_id, subject_id, sale_id) 
WHERE deleted_at IS NOT NULL 

लेकिन मुझे कोई कारण नहीं इतना परेशान करने के लिए जाने के लिए, विशेष रूप से विदेशी कुंजी के साथ संभावित समस्याओं को देखते हुए देखते हैं। अपनी मेज इस

create table feedback (
    feedback_id integer primary key, 
    user_id ... 
    subject_id ... 
    sale_id ... 
    deleted_at ... 
    constraint unique_user_subj_sale 
    unique (user_id, subject_id, sale_id) 
); 

की तरह लग रहा है, तो आप सभी की जरूरत है कि {user_id, subject_id, sale_id} पर अद्वितीय बाधा। आप हार्ड डिलीट करने के बजाय सभी हटाए गए "हटाए गए" कॉलम का उपयोग करने पर विचार कर सकते हैं।

+0

मैंने पूर्ण स्कीमा पोस्ट नहीं किया है, लेकिन फीडबैक में एक पूर्णांक (धारावाहिक) प्राथमिक कुंजी है। इसके अतिरिक्त, user_id, sale_id और topic_id को विदेशी कुंजी के रूप में घोषित किया जाता है (और अनुक्रमणिका होती है)। हमें विशिष्टता को एक अतिरिक्त बाधा के रूप में लागू करने की आवश्यकता है। – d11wtq

+0

और हाँ, अद्वितीय इंडेक्स के लिए यह ठीक है कि पंक्तियों को अनुमति देने के लिए केवल हटाए गए_एट टाइमस्टैम्प में भिन्न है ... यह वह चीज है जिसे मैं प्राप्त करने की कोशिश कर रहा था;) – d11wtq

+1

यदि आपके पास है) एक धारावाहिक प्राथमिक कुंजी, और बी) आंशिक जैसा कि आपने वर्णन किया है और जैसा कि मैंने परीक्षण किया है, आपके पास अभी भी "फीडबैक" संदर्भित अन्य तालिकाओं के साथ एक संभावित समस्या है। मान लें कि ऊपर दिए गए उदाहरण में पोस्ट की गई तीन पंक्तियों में धारावाहिक प्राथमिक कुंजी 1, 2, और 3. है। इनमें से कौन सा रेफरेंसिंग टेबल अपनी विदेशी कुंजी के लिए चुनता है? सभी रेफरेंसिंग टेबल * वही * मान चुनने के लिए कैसे जानेंगे? –

6

तथ्य PostgreSQL प्रलेखन (यदि बिंदु की कोई समस्या है) एक बाधा के बजाय एक अद्वितीय सूचकांक का उपयोग कर के खिलाफ सलाह देता है के बावजूद, यह प्रतीत होता है कि आप

CREATE UNIQUE INDEX feedback_unique_user_subject_and_sale 
ON feedback(user_id, subject_id, sale_id) 
WHERE deleted_at IS NULL 
+0

"आंशिक अनुक्रमणिका" के रूप में संदर्भित। महत्वपूर्ण सीमाओं के लिए @ कैटकॉल की पोस्ट देखें। –