दिलचस्प समस्याओं को हल करने के परिणामस्वरूप कई दिलचस्प तकनीकी समाधान उत्पन्न होते हैं। और जो इंजीनियरों के लिए ऐसी समस्याओं का आविष्कार या निर्माण करता है? जवाब बेशक उपयोगकर्ताओं का है। तो यह लेख सिर्फ एक ऐसी दिलचस्प समस्या और इसके समाधान के बारे में बात करता है।
So. सामान्य तौर पर, समस्या, उपयोगकर्ता के अनुसार, एक मुख्य ऑनलाइन स्टोर और कई अतिरिक्त बनाने की आवश्यकता की तरह दिखती है। मुख्य स्टोर में सामानों का पूरा डेटाबेस होता है। मुख्य स्टोर से सामानों की सूची का अनुरोध करके अतिरिक्त स्टोरों का सामान बनाया जाता है। मुख्य स्टोर, अतिरिक्त स्टोर से अनुरोध पर अपना पहचानकर्ता प्राप्त करता है, सही उत्पाद देता है।
अब एक इंजीनियर की आंखों के माध्यम से समस्या पर विचार करें, यह देखते हुए कि मुख्य और अतिरिक्त स्टोर के उत्पाद डेटाबेस एक ही सर्वर पर हैं। हम अतिरिक्त स्टोरों की संख्या नहीं जानते हैं, लेकिन यह स्पष्ट है कि मेन स्टोर पर लोड बड़ा होगा। विभिन्न उत्पादों की एक बड़ी संख्या हमें सामानों के साथ तालिकाओं की संरचना बनाने की अनुमति नहीं देती है। उत्पाद के गुण उसकी श्रेणी के आधार पर बहुत भिन्न होते हैं। डेटा को सारांशित करते हुए, मुख्य स्टोर के डिजाइनर के लिए कार्य ऐसा लगता है:
मेन स्टोर के डेटाबेस को डिज़ाइन करें ताकि सामान की सैंपलिंग की गति बहुत तेज़ हो, और माल के गुण, इसकी विशेषताएँ, गतिशील हों।
फूट डालो और जीतो!
"दिए गए" से, दो संस्थाओं की उपस्थिति इस प्रकार है। यह मुख्य स्टोर और वैकल्पिक है। आइए उन्हें बुलाते हैं।
प्राथमिक - प्राइमरीशॉप
वैकल्पिक - सेकेंडरीशॉप
यह भी स्पष्ट है कि अतिरिक्त स्टोर के भीतर, आपको मेन स्टोर के डेटा तक आंतरिक डेटा और बाहरी डेटा दोनों का उपयोग करना होगा। सुविधा के लिए, हम निम्नलिखित दो कार्य लिखते हैं:
function PrimaryShop($shop = null) { global $primaryshop, $shopId; if (!isset($shop) && !isset($shopId)) { die(" shopId "); } else { $shopId = isset($shop) ? $shop : $shopId; } if (Database::Setup(Config::Get("primaryDbHost"), Config::Get("primaryDbName"), Config::Get("primaryDbUser"), Config::Get("primaryDbPass"))->Connect()) { return isset($primaryshop) ? $primaryshop : new PrimaryGoods($shopId); } else { die(" "); } } function SecondaryShop() { if (Database::Setup(Config::Get("secondaryDbHost"), Config::Get("secondaryDbName"), Config::Get("secondaryDbUser"), Config::Get("secondaryDbPass"))->Connect()) { return new SecondaryGoods(); } else { die(" "); } }
तदनुसार, गौण और प्राथमिक वर्ग, जो संबंधित दुकानों के सामान के साथ काम करने के तरीकों को लागू करते हैं।
क्या वह सब है? बिल्कुल नहीं। ये कार्य आवरण हैं। वे हमें अंतिम लक्ष्य के करीब नहीं लाते हैं। आइए आगे तर्क करने की कोशिश करते हैं। एक नियम के रूप में, एक ऑनलाइन स्टोर उपयोगकर्ता को दो मोड में एक उत्पाद प्रदर्शित करता है। सूची दृश्य मोड और उत्पाद कार्ड दृश्य मोड। सूची दृश्य मोड के लिए डेटा प्राप्त करने की आवृत्ति स्पष्ट रूप से बहुत अधिक है, उत्पाद कार्ड देखने के लिए डेटा प्राप्त करने की आवृत्ति की तुलना में बहुत अधिक है। यहाँ से एक सरल निष्कर्ष का अनुसरण करता है। यदि मुख्य डेटाबेस में एक विशेष तालिका है, तो उन्हें उत्पाद सूची दृश्य मोड में प्रदर्शित करने के लिए तैयार डेटा वाली एक तालिका है, डेटा प्राप्त करने की गति कई तालिकाओं को एक में जोड़कर इस डेटा को उत्पन्न करने से अधिक होगी। उत्पाद को कार्ड मोड में देखने का डेटा एक मानक तरीके से उत्पन्न होता है, कई तालिकाओं को एक में जोड़कर।
मुख्य डेटाबेस के लिए क्वेरी का एक उदाहरण, कई तालिकाओं को एक में जोड़कर। इस तरह का अनुरोध एक प्राथमिकताओं को बिना कनेक्शन के एक साधारण अनुरोध की तुलना में धीमा होगा।
संक्षेप में कहना। हम रैपिंग फ़ंक्शन के माध्यम से एक विशेष स्टोर का उल्लेख करते हैं। सामानों की सूची के साथ एक पेज बनाने के लिए, हम एक विशेष टेबल बनाते हैं, जिसे विशेष रूप से इसके लिए डिज़ाइन किया गया है।
Mnogosvoystvennost
उत्पाद ए बनाने के लिए निम्नलिखित गुण हैं
- छोटी तस्वीर
- बड़ी तस्वीर
- आयाम
- सामग्री
- थोक मूल्य
- खुदरा मूल्य
और उत्पाद बी में निम्नलिखित गुण थे
- मध्य का चित्र
- बड़ी तस्वीर
- खुदरा मूल्य
- खुदरा मूल्य, विशेष
माल के सभी संभावित गुणों को पूर्व-बिछाने का कोई तरीका नहीं है। ठीक है, वास्तव में, न तो खाली कॉलम के साथ एक ही तालिका करें: Col1, Col2, ... ColN।
पहली बात जो मन में आती है वह है एक अतिरिक्त तालिका, एक संदर्भ। यह तालिका उत्पाद समूह के आधार पर संभावित उत्पाद विशेषताओं का एक सेट संग्रहीत करेगी। उत्पाद कार्ड प्राप्त करने की प्रक्रिया दो चरणों में प्राप्त की जाती है। स्टेज एक: संभावित विशेषताओं की एक सूची प्राप्त करें। चरण दो: इस सूची के अनुसार, हम आवश्यक तालिकाओं की ओर मुड़ते हैं और जानकारी एकत्र करते हैं। आप समझते हैं, प्रक्रिया तेज नहीं है। क्या वह फिट है? जवाब है नहीं।
यदि आप उत्पाद कार्ड की सामग्री को अधिक विस्तार से देखते हैं, तो आप उत्पाद गुणों को दो तालिकाओं में समूहित कर सकते हैं। तालिका एक होने दें, data_goods_images में सभी उत्पाद छवियों की एक सूची होगी, और data_goods_attr तालिका में अतिरिक्त विशेषताएँ होंगी।
CREATE TABLE IF NOT EXISTS `data_goods_full` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goodsId` int(11) NOT NULL, `categoryId` int(11) NOT NULL, `shopId` int(11) NOT NULL, `article` varchar(150) NOT NULL, `intro` varchar(255) NOT NULL, `name` varchar(150) NOT NULL, `description` text NOT NULL, PRIMARY KEY (`id`), KEY `categoryId` (`categoryId`), KEY `goodsId` (`goodsId`), KEY `shopId` (`shopId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=501 ; CREATE TABLE IF NOT EXISTS `data_goods_images` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goodsId` int(11) NOT NULL, `shopId` int(11) NOT NULL, `type` enum('','','') NOT NULL, `value` varchar(150) NOT NULL, PRIMARY KEY (`id`), KEY `goodsId` (`goodsId`), KEY `shopId` (`shopId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE IF NOT EXISTS `data_goods_attr` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goodsId` int(11) NOT NULL, `type` enum('','','','') DEFAULT NULL, `value` varchar(150) NOT NULL, PRIMARY KEY (`id`), KEY `goodsId` (`goodsId`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
तालिका data_goods_images और data_goods_attr में टाइप फ़ील्ड पर ध्यान दें। यह एक प्रकार का ENUM है। यह प्रकार सूची से मान ले सकता है। अब एक निवेदन करते हुए और इसमें इन तीन तालिकाओं के संयोजन से, हमें उत्पाद की सभी विशेषताएं मिलती हैं
SELECT * FROM `data_goods_full` AS `a` LEFT JOIN `data_goods_images` AS `b` ON `b`.`goodsId` = `a`.`goodsId` LEFT JOIN `data_goods_attr` AS `c` ON `c`.`goodsId` = `a`.`goodsId`
हम बिना कनेक्शन के भी, कोई भी विशिष्ट गुण प्राप्त कर सकते हैं। उदाहरण के लिए, मैं केवल छोटे चित्र, उत्पाद बी। उत्पाद पहचानकर्ता प्राप्त करना चाहता हूं, इसे 100 के बराबर होने दें
SELECT * FROM `data_goods_images` WHERE `type` = '' AND `goodsId` = '100'
अब उस प्रश्न पर वापस आते हैं, जिसे अध्याय की शुरुआत में आवाज़ दी गई थी। सामान बनाने के लिए A के पास एक संपत्ति है और माल B के पास अलग-अलग गुण हैं। हमारे मामले में, हमें data_goods_attr तालिका में अतिरिक्त प्रकार के उत्पाद गुण जोड़ने होंगे, जैसे: खुदरा मूल्य, थोक मूल्य और खुदरा मूल्य, विशेष। आप निम्न आदेश के साथ ऐसा कर सकते हैं:
ALTER TABLE `data_goods_attr` CHANGE `type` `type` ENUM('','','','',' ',' ',' , ')
अब डेटाबेस माल ए और माल बी (माल 100 और माल 101) में जोड़ें
ठीक है, अब, चलो पढ़ते हैं, सब कुछ जो हम डेटाबेस में डालते हैं। छोटे के बाद
क्वेरी परिणाम में हेरफेर करने पर, हमें निम्नलिखित मिलते हैं:
Array ( [property] => stdClass Object ( [id] => 1 [categoryId] => 1 [article] => -100 [intro] => [name] => [text] => ) [images] => Array ( [0] => stdClass Object ( [imageType] => [imageValue] => small_a.png ) [1] => stdClass Object ( [imageType] => [imageValue] => big_a.png ) ) [attributes] => Array ( [0] => stdClass Object ( [attrType] => [attrValue] => XL ) [1] => stdClass Object ( [attrType] => [attrValue] => ) [2] => stdClass Object ( [attrType] => [attrValue] => 100 . ) [3] => stdClass Object ( [attrType] => [attrValue] => 125 . ) ) ) Array ( [property] => stdClass Object ( [id] => 2 [categoryId] => 1 [article] => -101 [intro] => [name] => [text] => ) [images] => Array ( [0] => stdClass Object ( [imageType] => [imageValue] => midle_b.png ) [1] => stdClass Object ( [imageType] => [imageValue] => big_b.png ) ) [attributes] => Array ( [0] => stdClass Object ( [attrType] => [attrValue] => 125 . ) [1] => stdClass Object ( [attrType] => , [attrValue] => 120 . ) ) )
निष्कर्ष
एनम प्रकार के क्षेत्रों के साथ काम करने के लिए, गुणों को हटाने और जोड़ने के लिए, आपको इन क्षेत्रों के मूल्यों की एक सूची प्राप्त करने में सक्षम होने की आवश्यकता है। यह सूची SQL DESCRIBE कमांड का उपयोग करके प्राप्त की जा सकती है। नीचे, मैं इस तरह के एक समारोह का एक उदाहरण दूंगा:
function GetImagesSet() { $query = "\n DESCRIBE `data_goods_images` `type`"; if ($result = Database::Exec($query)->Read(0, "Type")) { $result = str_replace(array("enum", "(", ")", "'"), array("", "", "", ""), $result); return $result ? explode(",", $result) : $result; } } function AddImagesSet($type = null) { if (isset($type)) { $result = $this->GetImagesSet(); if (!empty($result)) { foreach ($result as $item) { $enum[] = "'".$item."'"; } $enum = implode(",", $enum).","; } else { $enum = ""; } $enum = $enum.str_replace(" ", "", $type); $query = "\n ALTER TABLE `d ata_goods_images` CHANGE `type` `type` ENUM(".$enum.")"; return Database::Exec($query)->Read(); } else { return false; } } function DelImagesSet($type = null) { if (isset($type)) { foreach(self::GetImagesSet() as $value) { if ($type != $value) { $enum[] = "'".$value."'"; } } $query = "\n ALTER TABLE `data_goods_images` CHANGE `type` `type` ENUM(".implode(",", $enum).")"; return Database::Exec($query)->Read(); } else { return false; } }
आप सब कुछ एक
फ़ाइल में भी डाउनलोड कर सकते हैं
।