एकल कॉलम से कई तालिकाओं को संदर्भित करने के लिए सबसे अच्छा डिज़ाइन?


18

प्रस्तावित स्कीमा

सबसे पहले और सबसे महत्वपूर्ण, यहाँ मेरी प्रस्तावित स्कीमा का एक उदाहरण है जो मेरी पूरी पोस्ट के संदर्भ में है:

Clothes
---------- 
ClothesID (PK) INT NOT NULL
Name VARCHAR(50) NOT NULL
Color VARCHAR(50) NOT NULL
Price DECIMAL(5,2) NOT NULL
BrandID INT NOT NULL
...

Brand_1
--------
ClothesID (FK/PK) int NOT NULL
ViewingUrl VARCHAR(50) NOT NULL
SomeOtherBrand1SpecificAttr VARCHAR(50) NOT NULL

Brand_2
--------
ClothesID (FK/PK) int NOT NULL
PhotoUrl VARCHAR(50) NOT NULL
SomeOtherBrand2SpecificAttr VARCHAR(50) NOT NULL

Brand_X
--------
ClothesID (FK/PK) int NOT NULL
SomeOtherBrandXSpecificAttr VARCHAR(50) NOT NULL

समस्या का विवरण

मेरे पास एक कपड़े की मेज है जिसमें कपड़ों , नाम, रंग, कीमत, ब्रैंडिड जैसे कॉलम हैं और कपड़ों की एक विशेष वस्तु के लिए विशेषताओं का वर्णन करना है।

यहाँ मेरी समस्या है: अलग-अलग ब्रांड के कपड़ों के लिए अलग-अलग जानकारी की आवश्यकता होती है। इस तरह की समस्या से निपटने के लिए सबसे अच्छा अभ्यास क्या है?

ध्यान दें कि मेरे उद्देश्यों के लिए, कपड़ों की प्रविष्टि से शुरू होने वाली ब्रांड-विशिष्ट जानकारी ढूंढना आवश्यक है । ऐसा इसलिए है क्योंकि मैं पहली बार उपयोगकर्ता को कपड़ों की प्रविष्टि से जानकारी प्रदर्शित करता हूं , जिसके बाद मुझे आइटम खरीदने के लिए इसकी ब्रांड-विशिष्ट जानकारी का उपयोग करना होगा। सारांश में, कपड़े (से) और ब्रांड_x तालिकाओं के बीच एक दिशात्मक संबंध होना चाहिए ।

प्रस्तावित / वर्तमान समाधान

इससे निपटने के लिए, मैंने निम्नलिखित डिजाइन योजना के बारे में सोचा है:

कपड़े तालिका एक होगा ब्रांड स्तंभ जो आईडी 1 से एक्स, को लेकर मान हो सकता है, जहां एक खास ब्रांड के मेज पर एक विशेष आईडी मेल खाती है। उदाहरण के लिए, आईडी वैल्यू 1 टेबल ब्रांड 1 के अनुरूप होगा (जिसमें एक यूआरएल कॉलम हो सकता है ), आईडी 2 ब्रांड 2 के अनुरूप होगा (जिसमें सप्लायर कॉलम हो सकता है ), आदि।

इस प्रकार अपनी ब्रांड-विशिष्ट जानकारी के साथ एक विशेष कपड़े प्रविष्टि को संबद्ध करने के लिए, मुझे लगता है कि एप्लिकेशन-स्तर पर तर्क कुछ इस तरह दिखाई देगा:

clothesId = <some value>
brand = query("SELECT brand FROM clothes WHERE id = clothesId")

if (brand == 1) {
    // get brand_1 attributes for given clothesId
} else if (brand == 2) {
    // get brand_2 attributes for given clothesId
} ... etc.

अन्य टिप्पणियाँ और विचार

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

अनुसंधान

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

मैं भी एक नौसिखिया की तरह हूँ जब यह डेटाबेस डिजाइन की बात आती है, और इसलिए मैं किसी भी अंतर्दृष्टि की सराहना करता हूं।


ऐसा प्रतीत होता है कि स्टैक ओवरफ्लो पर अधिक सहायक प्रतिक्रियाएं हैं:

मैंने वहां के समाधानों का उल्लेख किया है और सुझाव दिया है कि मेरे प्रश्न का पता लगाने वाले अन्य लोग भी ऐसा करें।

उपरोक्त प्रदान किए गए लिंक के बावजूद, मैं अभी भी यहां प्रतिक्रियाओं की तलाश में हूं और प्रदान किए गए किसी भी समाधान की सराहना करूंगा!

मैं PostgreSQL का उपयोग कर रहा हूं।

जवाबों:


7

मैं व्यक्तिगत रूप से इस उद्देश्य के लिए मल्टी-टेबल स्कीमा का उपयोग करना पसंद नहीं करता।

  • अखंडता सुनिश्चित करना कठिन है।
  • इसे बनाए रखना कठिन है।
  • परिणामों को फ़िल्टर करना मुश्किल है।

मैंने एक dbfiddle नमूना निर्धारित किया है ।

मेरी प्रस्तावित तालिका स्कीमा:

CREATE TABLE #Brands
(
BrandId int NOT NULL PRIMARY KEY,
BrandName nvarchar(100) NOT NULL 
);

CREATE TABLE #Clothes
(
ClothesId int NOT NULL PRIMARY KEY,
ClothesName nvarchar(100) NOT NULL 
);

-- Lookup table for known attributes
--
CREATE TABLE #Attributes
(
AttrId int NOT NULL PRIMARY KEY,
AttrName nvarchar(100) NOT NULL 
);

-- holds common propeties, url, price, etc.
--
CREATE TABLE #BrandsClothes
(
BrandId int NOT NULL REFERENCES #Brands(BrandId),
ClothesId int NOT NULL REFERENCES #Clothes(ClothesId),
VievingUrl nvarchar(300) NOT NULL,
Price money NOT NULL,
PRIMARY KEY CLUSTERED (BrandId, ClothesId),
INDEX IX_BrandsClothes NONCLUSTERED (ClothesId, BrandId)
);

-- holds specific and unlimited attributes 
--
CREATE TABLE #BCAttributes
(
BrandId int NOT NULL REFERENCES #Brands(BrandId),
ClothesId int NOT NULL REFERENCES #Clothes(ClothesId),
AttrId int NOT NULL REFERENCES #Attributes(AttrId),
AttrValue nvarchar(300) NOT NULL,
PRIMARY KEY CLUSTERED (BrandId, ClothesId, AttrId),
INDEX IX_BCAttributes NONCLUSTERED (ClothesId, BrandId, AttrId)
);

मुझे कुछ डेटा डालने दें:

INSERT INTO #Brands VALUES 
(1, 'Brand1'), (2, 'Brand2');

INSERT INTO #Clothes VALUES 
(1, 'Pants'), (2, 'T-Shirt');

INSERT INTO #Attributes VALUES
(1, 'Color'), (2, 'Size'), (3, 'Shape'), (4, 'Provider'), (0, 'Custom');

INSERT INTO #BrandsClothes VALUES
(1, 1, 'http://mysite.com?B=1&C=1', 123.99),
(1, 2, 'http://mysite.com?B=1&C=2', 110.99),
(2, 1, 'http://mysite.com?B=2&C=1', 75.99),
(2, 2, 'http://mysite.com?B=2&C=2', 85.99);

INSERT INTO #BCAttributes VALUES
(1, 1, 1, 'Blue, Red, White'),
(1, 1, 2, '32, 33, 34'),
(1, 2, 1, 'Pearl, Black widow'),
(1, 2, 2, 'M, L, XL'),
(2, 1, 4, 'Levis, G-Star, Armani'),
(2, 1, 3, 'Slim fit, Regular fit, Custom fit'),
(2, 2, 4, 'G-Star, Armani'),
(2, 2, 3, 'Slim fit, Regular fit'),
(2, 2, 0, '15% Discount');

यदि आपको सामान्य विशेषताएँ प्राप्त करने की आवश्यकता है:

SELECT     b.BrandName, c.ClothesName, bc.VievingUrl, bc.Price
FROM       #BrandsClothes bc
INNER JOIN #Brands b
ON         b.BrandId = bc.BrandId
INNER JOIN #Clothes c
ON         c.ClothesId = bc.ClothesId
ORDER BY   bc.BrandId, bc.ClothesId;

BrandName   ClothesName   VievingUrl                  Price
---------   -----------   -------------------------   ------
Brand1      Pants         http://mysite.com?B=1&C=1   123.99
Brand1      T-Shirt       http://mysite.com?B=1&C=2   110.99
Brand2      Pants         http://mysite.com?B=2&C=1    75.99
Brand2      T-Shirt       http://mysite.com?B=2&C=2    85.99

या आप आसानी से ब्रांड द्वारा कपड़े प्राप्त कर सकते हैं:

मुझे Brand2 के सभी कपड़े दें

SELECT     c.ClothesName, b.BrandName, a.AttrName, bca.AttrValue
FROM       #BCAttributes bca
INNER JOIN #BrandsClothes bc
ON         bc.BrandId = bca.BrandId
AND        bc.ClothesId = bca.ClothesId
INNER JOIN #Brands b
ON         b.BrandId = bc.BrandId
INNER JOIN #Clothes c
ON         c.ClothesId = bc.ClothesId
INNER JOIN #Attributes a
ON         a.AttrId = bca.AttrId
WHERE      bca.ClothesId = 2
ORDER BY   bca.ClothesId, bca.BrandId, bca.AttrId;

ClothesName   BrandName   AttrName   AttrValue
-----------   ---------   --------   ---------------------
T-Shirt       Brand1      Color      Pearl, Black widow
T-Shirt       Brand1      Size       M, L, XL
T-Shirt       Brand2      Custom     15% Discount
T-Shirt       Brand2      Shape      Slim fit, Regular fit
T-Shirt       Brand2      Provider   G-Star, Armani

लेकिन मेरे लिए, इस स्कीमा में सबसे अच्छी बात यह है कि आप Attibutes द्वारा फ़िल्टर कर सकते हैं:

मुझे वे सभी कपड़े दें जिनकी विशेषता है: आकार

SELECT     c.ClothesName, b.BrandName, a.AttrName, bca.AttrValue
FROM       #BCAttributes bca
INNER JOIN #BrandsClothes bc
ON         bc.BrandId = bca.BrandId
AND        bc.ClothesId = bca.ClothesId
INNER JOIN #Brands b
ON         b.BrandId = bc.BrandId
INNER JOIN #Clothes c
ON         c.ClothesId = bc.ClothesId
INNER JOIN #Attributes a
ON         a.AttrId = bca.AttrId
WHERE      bca.AttrId = 2
ORDER BY   bca.ClothesId, bca.BrandId, bca.AttrId;

ClothesName   BrandName   AttrName   AttrValue
-----------   ---------   --------   ----------
Pants         Brand1      Size       32, 33, 34
T-Shirt       Brand1      Size       M, L, XL

मल्टी-टेबल स्कीमा का उपयोग करके पिछले प्रश्नों में से जो भी असीमित संख्या में तालिकाओं के साथ, या XML या JSON फ़ील्ड्स से निपटने के लिए आवश्यक होगा।

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

मुझे खेद है, मैं अपनी व्याख्याएं विस्तार से करना चाहूंगा, क्योंकि मुझे लगता है कि यह मेरी अंग्रेजी से अधिक स्पष्ट है।

अपडेट करें

मेरे वर्तमान उत्तर को किसी भी मामले पर काम नहीं करना चाहिए जो RDBMS है। आपकी टिप्पणियों के अनुसार, यदि आपको उन विशेषताओं मानों को फ़िल्टर करने की आवश्यकता है जो मैं छोटे बदलावों का सुझाव दूंगा।

जहाँ तक MS-Sql सरणियों की अनुमति नहीं देता है, मैंने एक ही तालिका स्कीमा एक नया नमूना mantaining की स्थापना की है , लेकिन AttrValue को ARRAY फ़ील्ड प्रकार में बदल रहा है।

वास्तव में, POSTGRES का उपयोग करते हुए, आप GIN इंडेक्स का उपयोग करके इस सरणी का लाभ ले सकते हैं।

(मुझे कहना होगा कि @EvanCarrol को Postgres के बारे में अच्छी जानकारी है, निश्चित रूप से मुझसे बेहतर है। लेकिन मुझे थोड़ा सा जोड़ने दें।)

CREATE TABLE BCAttributes
(
BrandId int NOT NULL REFERENCES Brands(BrandId),
ClothesId int NOT NULL REFERENCES Clothes(ClothesId),
AttrId int NOT NULL REFERENCES Attrib(AttrId),
AttrValue text[],
PRIMARY KEY (BrandId, ClothesId, AttrId)
);

CREATE INDEX ix_attributes on BCAttributes(ClothesId, BrandId, AttrId);
CREATE INDEX ix_gin_attributes on BCAttributes using GIN (AttrValue);


INSERT INTO BCAttributes VALUES
(1, 1, 1, '{Blue, Red, White}'),
(1, 1, 2, '{32, 33, 34}'),
(1, 2, 1, '{Pearl, Black widow}'),
(1, 2, 2, '{M, L, XL}'),
(2, 1, 4, '{Levis, G-Star, Armani}'),
(2, 1, 3, '{Slim fit, Regular fit, Custom fit}'),
(2, 2, 4, '{G-Star, Armani}'),
(2, 2, 3, '{Slim fit, Regular fit}'),
(2, 2, 0, '{15% Discount}');

अब, आप अतिरिक्त व्यक्तिगत विशेषताओं जैसे मानों का उपयोग करके क्वेरी कर सकते हैं:

मुझे सभी पैंट की सूची दें आकार: 33

AttribId = 2 AND ARRAY['33'] && bca.AttrValue

SELECT     c.ClothesName, b.BrandName, a.AttrName, array_to_string(bca.AttrValue, ', ')
FROM       BCAttributes bca
INNER JOIN BrandsClothes bc
ON         bc.BrandId = bca.BrandId
AND        bc.ClothesId = bca.ClothesId
INNER JOIN Brands b
ON         b.BrandId = bc.BrandId
INNER JOIN Clothes c
ON         c.ClothesId = bc.ClothesId
INNER JOIN Attrib a
ON         a.AttrId = bca.AttrId
WHERE      bca.AttrId = 2
AND        ARRAY['33'] && bca.AttrValue
ORDER BY   bca.ClothesId, bca.BrandId, bca.AttrId;

यह परिणाम है:

clothes name | brand name | attribute | values 
------------- ------------ ----------  ---------------- 
Pants          Brand1       Size        32, 33, 34

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

दरअसल ... मैंने जो समस्या बताई है, उसका उत्तर देने के लिए, शायद उत्तर @ EvanCarroll के समाधान से उधार लिया जा सकता है: अर्थात्, CSV प्रारूप में केवल TEXT / STRINGS के बजाय jsonb प्रकारों का उपयोग करके। लेकिन फिर से - अगर इस अवधारणा का कोई नाम है, तो कृपया मुझे बताएं!
यंगर्रर

1
यह एक संपूर्ण गुण मूल्य समाधान है। यह प्रदर्शन और अच्छे डिजाइन के बीच एक बुरा समझौता नहीं है। यह एक व्यापार है, हालांकि। आप क्लीनर डिज़ाइन के लिए कुछ प्रदर्शन करते हैं, अंतहीन "Brand_X" तालिकाओं के साथ नहीं। निष्पादन दंड, आपके द्वारा बताई गई सबसे सामान्य दिशा से जाना न्यूनतम होना चाहिए। दूसरे रास्ते पर जाना अधिक दर्दनाक होगा, लेकिन यह समझौता है। en.wikipedia.org/wiki/…
जोनाथन फाइट

4

आप जो वर्णन कर रहे हैं, वह कम से कम भाग में, एक उत्पाद सूची है। आपके पास कई विशेषताएं हैं जो सभी उत्पादों के लिए सामान्य हैं। ये एक अच्छी तरह से सामान्यीकृत तालिका में हैं।

इसके अलावा, आपके पास विशेषताओं की एक श्रृंखला है जो ब्रांड विशिष्ट हैं (और मुझे उम्मीद है कि उत्पाद विशिष्ट हो सकता है)। इन विशिष्ट विशेषताओं के साथ आपके सिस्टम को क्या करने की आवश्यकता है? क्या आपके पास व्यावसायिक तर्क हैं जो इन विशेषताओं के स्कीमा पर निर्भर करता है या क्या आप उन्हें "लेबल": "मूल्य" जोड़े की एक श्रृंखला में सूचीबद्ध कर रहे हैं?

अन्य उत्तर यह सुझाव दे रहे हैं कि अनिवार्य रूप से एक CSV दृष्टिकोण (चाहे यह है JSONया ARRAYअन्यथा) का उपयोग कर रहे हैं - ये दृष्टिकोण मेटाडेटा से स्कीमा को स्थानांतरित करके और डेटा में ही नियमित रूप से संबंधपरक स्कीमा हैंडलिंग से संपर्क करते हैं।

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

ईएवी के खिलाफ सभी सामान्य तर्क एक उत्पाद सुविधा कैटलॉग पर लागू नहीं होते हैं, क्योंकि उत्पाद सुविधा मान आमतौर पर केवल सूची में सबसे खराब स्थिति में होते हैं या सबसे खराब स्थिति में तुलना करते हैं।

JSONस्तंभ प्रकार का उपयोग करने से डेटाबेस से बाहर किसी भी डेटा की कमी को लागू करने की आपकी क्षमता होती है और इसे आपके एप्लिकेशन लॉजिक में मजबूर कर देता है। इसके अलावा, प्रत्येक ब्रांड के लिए एक विशेषता तालिका का उपयोग करने के निम्नलिखित नुकसान हैं:

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

ब्रांड-विशिष्ट विशेषताओं वाले उत्पाद के बारे में डेटा प्राप्त करना विशेष रूप से मुश्किल नहीं है। टेबल-प्रति-श्रेणी मॉडल का उपयोग करते हुए ईएवी मॉडल का उपयोग करके गतिशील एसक्यूएल बनाना यकीनन आसान है। तालिका-प्रति-श्रेणी में, आपको JSONयह पता लगाने के लिए प्रतिबिंब (या आपके ) की आवश्यकता है कि फीचर कॉलम नाम क्या हैं। फिर आप एक खंड के लिए मदों की एक सूची बना सकते हैं। ईएवी मॉडल में, WHERE X AND Y AND Zबन जाता है INNER JOIN X INNER JOIN Y INNER JOIN Z, इसलिए क्वेरी थोड़ी अधिक जटिल है, लेकिन क्वेरी बनाने के लिए तर्क अभी भी पूरी तरह से टेबल-संचालित है और यह उचित स्केलेबल से अधिक होगा यदि आपने उचित इंडेक्स बनाया है।

सामान्य दृष्टिकोण के रूप में ईएवी का उपयोग नहीं करने के कई कारण हैं। वे कारण किसी उत्पाद सुविधा कैटलॉग पर लागू नहीं होते हैं, इसलिए इस विशिष्ट एप्लिकेशन में EAV के साथ कुछ भी गलत नहीं है।

निश्चित रूप से, यह एक जटिल और विवादास्पद विषय के लिए एक संक्षिप्त जवाब है। मैंने पहले भी इसी तरह के सवालों के जवाब दिए हैं और ईएवी के सामान्य टकराव के बारे में अधिक विस्तार से जाना है। उदाहरण के लिए:

मैं कहूंगा कि ईएवी का उपयोग कम से कम अक्सर किया जाता है क्योंकि यह ज्यादातर अच्छे कारणों के लिए इस्तेमाल किया जाता है। हालाँकि, मुझे लगता है कि यह भी अच्छी तरह से नहीं समझा गया है।


3

यहाँ मेरी समस्या है: विभिन्न ब्रांडों के कपड़ों के लिए अलग-अलग जानकारी की आवश्यकता होती है। इस तरह की समस्या से निपटने के लिए सबसे अच्छा अभ्यास क्या है?

JSON और PostgreSQL का उपयोग करना

मुझे लगता है कि आप इसे और अधिक कठिन बना रहे हैं क्योंकि आपको इसकी आवश्यकता है और आप बाद में इसके साथ काट लेंगे। आप की जरूरत नहीं है इकाई-विशेषता-मूल्य मॉडल जब तक आप वास्तव में EAV की जरूरत है।

CREATE TABLE brands (
  brand_id     serial PRIMARY KEY,
  brand_name   text,
  attributes   jsonb
);
CREATE TABLE clothes (
  clothes_id   serial        PRIMARY KEY,
  brand_id     int           NOT NULL REFERENCES brands,
  clothes_name text          NOT NULL,
  color        text,
  price        numeric(5,2)  NOT NULL
);

इस स्कीमा में कुछ भी गलत नहीं है।

INSERT INTO brands (brand_name, attributes)
VALUES
  ( 'Gucci', $${"luxury": true, "products": ["purses", "tawdry bougie thing"]}$$ ),
  ( 'Hugo Boss', $${"origin": "Germany", "known_for": "Designing uniforms"}$$ ),
  ( 'Louis Vuitton', $${"origin": "France", "known_for": "Designer Purses"}$$ ),
  ( 'Coco Chanel', $${"known_for": "Spying", "smells_like": "Banana", "luxury": true}$$ )
;

INSERT INTO clothes (brand_id, clothes_name, color, price) VALUES
  ( 1, 'Purse', 'orange', 100 ),
  ( 2, 'Underwear', 'Gray', 10 ),
  ( 2, 'Boxers', 'Gray', 10 ),
  ( 3, 'Purse with Roman Numbers', 'Brown', 10 ),
  ( 4, 'Spray', 'Clear', 100 )
;

अब आप इसे एक साधारण जोड़ का उपयोग करके क्वेरी कर सकते हैं

SELECT *
FROM brands
JOIN clothes
  USING (brand_id);

और JSON ऑपरेटरों में से कोई भी एक क्लॉज में काम करता है।

SELECT *
FROM brands
JOIN clothes
  USING (brand_id)
WHERE attributes->>'known_for' ILIKE '%Design%';

एक साइड नोट के रूप में, यूआरएल को डेटाबेस में न रखें। वे समय के साथ बदलते हैं। बस एक फ़ंक्शन बनाएं जो उन्हें लेता है।

generate_url_brand( brand_id );
generate_url_clothes( clothes_id );

जो कुछ भी। यदि आप PostgreSQL का उपयोग कर रहे हैं तो आप हैशिड का भी उपयोग कर सकते हैं ।

विशेष नोट के अलावा, jsonbबाइनरी के रूप में संग्रहीत किया जाता है (इस प्रकार -'बी ') और यह सूचकांक-सक्षम, या SARGable या जो कुछ और शांत बच्चे इसे इन दिनों बुला रहे हैं:CREATE INDEX ON brands USING gin ( attributes );

यहाँ अंतर क्वेरी की सादगी में है ।।

मुझे Brand2 के सभी कपड़े दें

SELECT * FROM clothes WHERE brand_id = 2;

मुझे वे सभी कपड़े दें जिनकी विशेषता है: आकार

SELECT * FROM clothes WHERE attributes ? 'size';

कैसे एक अलग के बारे में ..

मुझे सभी कपड़े और बड़े में उपलब्ध किसी भी कपड़े के लिए विशेषताएँ दें।

SELECT * FROM clothes WHERE attributes->>'size' = 'large';

इसलिए, अगर मैं सही ढंग से समझूं, तो आपने जो कहा है उसका सार है यदि ब्रांडों और विशेषताओं (यानी यह वैध है या नहीं) के बीच एक संबंध है, तो मैकनेट्स समाधान को प्राथमिकता दी जाएगी (लेकिन प्रश्न अधिक महंगे / धीमे होंगे)। दूसरी ओर, यदि यह संबंध महत्वपूर्ण / अधिक "तदर्थ" नहीं है, तो कोई आपके समाधान को प्राथमिकता दे सकता है। क्या आप इसका मतलब थोड़ा और बता सकते हैं जब आपने कहा था कि "मैं इसे PostgreSQL के साथ कभी भी उपयोग नहीं करूंगा?" उस टिप्पणी पर कोई स्पष्टीकरण नहीं लगता था। सभी प्रश्नों के लिए क्षमा करें!! मैं वास्तव में आपके अब तक के जवाबों की सराहना करता हूं :)
युवाग्र्र

1
स्पष्ट रूप से एक रिश्ता है, एकमात्र सवाल यह है कि आपको इसे प्रबंधित करने की कितनी आवश्यकता है। यदि मैं गुणों , विशेषताओं या पसंद जैसे अस्पष्ट शब्द का उपयोग कर रहा हूं , तो मेरा आमतौर पर यह कहने का मतलब है कि यह बहुत अधिक तदर्थ या अत्यधिक बाधित है। उसके लिए, JSONB सिर्फ बेहतर है क्योंकि यह सरल है। आपको यह पोस्ट जानकारीपूर्ण coussej.github.io/2016/01/14/… पर
इवान कैरोल

-1

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


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