मैं व्यक्तिगत रूप से इस उद्देश्य के लिए मल्टी-टेबल स्कीमा का उपयोग करना पसंद नहीं करता।
- अखंडता सुनिश्चित करना कठिन है।
- इसे बनाए रखना कठिन है।
- परिणामों को फ़िल्टर करना मुश्किल है।
मैंने एक 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