2010-07-16 22 views
13

मुझे दो टेबल मिल गए हैंएक MySQL कॉलम में पूर्णांक की सरणी को स्टोर करने का सबसे प्रभावी तरीका क्या है?

ए:

plant_ID | name. 
1  | tree 
2  | shrubbery 
20  | notashrubbery 

बी:

area_ID | name | plants 
1  | forrest | *needhelphere* 

अब मैं चाहता हूं कि क्षेत्र किसी भी क्रम में पौधों को स्टोर करे, एक विशिष्ट क्रम में और कुछ पौधे दिखाए जा सकते हैं कई बार: उदाहरण के लिए 2,20,1,2,2,20,1

पौधों की इस सरणी को स्टोर करने का सबसे प्रभावी तरीका क्या है?
ध्यान में रखते हुए मुझे इसे बनाने की ज़रूरत है ताकि अगर मैं पौधे 2 के साथ क्षेत्रों को खोजने के लिए खोज करता हूं, तो मुझे ऐसे क्षेत्र नहीं मिलते हैं, जैसे 1,20,232,12,20 (अग्रणी 0 के साथ पैड?) क्या इसके लिए पूछताछ होगी?

अगर यह मदद करता है, मान लीजिए कि मेरे पास 99 99 99 99 से अधिक विभिन्न पौधों का डेटाबेस नहीं है। और हाँ, इस सवाल के पौधों के साथ कुछ भी नहीं है ....

बोनस प्रश्न क्या यह MySQL से दूर जाने का समय है? क्या इसका प्रबंधन करने के लिए एक बेहतर डीबी है?

+2

यदि केवल MySQL ही हमें एक ही कॉलम के लिए कई मान हैं ... – animuson

+6

किसी भी समय आपको एक फ़ील्ड में डेटा गठबंधन करने की आवश्यकता महसूस होती है, तो खुद को लातें: आप सामान्य रूप का उल्लंघन कर रहे हैं और हैंडल करने के लिए एक और टेबल जोड़ने की आवश्यकता है स्थिति ठीक से। (नीचे मिलानू और एमग्रोव के उत्तरों को देखें।) –

+0

यदि आप इस डेटा को स्टोर करने के लिए एक गैर-रिलेशनल तरीका रुचि रखते हैं (यानी एक वास्तविक संग्रह/सरणी), तो ओबीबीबीएमएस जैसे डीबी 4o देखें। –

उत्तर

25

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

क्षेत्र 1 पौधों 1 और 2, और क्षेत्र 2 पौधों 2 और 3 है है, तो आपके areas_plants तालिका इस प्रकार दिखाई देगा:

area_id | plant_id | sort_idx 
----------------------------- 
     1 |  1 |  0 
     1 |  2 |  1 
     2 |  2 |  0 
     2 |  3 |  1 

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

+6

यह (एक जॉइन टेबल पेश करना) समस्या का सही समाधान है। प्रश्न में अनुरोध किए गए प्लांट ऑर्डर को बनाए रखने के लिए एकमात्र चीज जो मैं जोड़ूंगा वह एक sort_idx कॉलम है। –

+0

@ पॉल सासिक - अच्छी तरह से देखा गया :) संपादन को परेशान नहीं करेगा, क्योंकि आपको पहले ही जवाब मिल गया है। – Matchu

+1

मैं आगे बढ़ गया और कॉलम जोड़ा। यह मुझे लगता है कि डीबी डिजाइन Noobs के लिए pedantic के पक्ष में गलती करने में मदद करता है। –

3

क्या आप जानते हैं कि यह सामान्य रूप का उल्लंघन करता है?

आमतौर पर, एक के पास एक सारणी तालिका होगी: area_ID, plant_ID दो और विदेशी कुंजियों पर एक अद्वितीय बाधा के साथ अन्य दो तालिकाओं के लिए। यह "लिंक" तालिका आपको कई-कई या कई से एक रिश्ते देता है।

इस पर क्वेरी आमतौर पर बहुत ही कुशल हैं, वे इंडेक्स का उपयोग करते हैं और पार्सिंग स्ट्रिंग की आवश्यकता नहीं होती है।

+0

+1: लेकिन समग्र प्राथमिक कुंजी> समग्र अद्वितीय बाधा –

+0

@OMG टट्टू, हाँ, लेकिन कभी-कभी लोग उस तालिका पर एक सरोगेट कुंजी चाहते हैं। –

+0

ओआरएम, और माइली साइरस जैसे लोग ... –

2

आपके संबंध विशेषताओं परमाणु होना चाहिए, सूचियों जैसे कई मानों से बना नहीं है। उन्हें खोजना बहुत मुश्किल है। आपको एक नए संबंध की आवश्यकता है जो पौधों को क्षेत्र_आईडी में मानचित्रित करे और क्षेत्र_आईडी/पौधे संयोजन प्राथमिक कुंजी है।

7

कैसे इस बारे में:

तालिका: पौधों

plant_ID | name 
1  | tree 
2  | shrubbery 
20  | notashrubbery 

तालिका: क्षेत्रों

area_ID | name 
1  | forest 

तालिका: area_plant_map

area_ID | plant_ID | sequence 
1  | 1  | 0 
1  | 2  | 1 
1  | 20  | 2 

यह करने के लिए मानक सामान्यीकृत तरीका है कि (साथ में मैपिंग टेबल)।

एक झाड़ी का जंगल (संयंत्र 2) के साथ सभी क्षेत्रों को खोजने के लिए ऐसा करते हैं:

SELECT * 
FROM areas 
INNER JOIN area_plant_map ON areas.area_ID = area_plant_map.area_ID 
WHERE plant_ID = 2 
+3

मैंने "शर्बेरी" पढ़ा और अब नाइट्स ऑफ नेई है! मेरे सिर के माध्यम से चल रहा है ... –

+0

प्रश्न देखें - क्षेत्र 1 में पौधों का यह अनुक्रम हो सकता है: 2,20,1,2,2,20,1 (इसलिए क्षेत्र 1 में 0,3 और 4 स्थिति पर 3 shrubberies है) – Moak

+0

उस मामले में @ मोक, बस अनुक्रम संख्या के साथ एक और कॉलम डालें। –

2

उपयोग कई-से-अनेक संबंध:

CREATE TABLE plant (
    plant_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(255) 
) ENGINE=INNODB; 

CREATE TABLE area (
    area_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    name VARCHAR(255) 
) ENGINE=INNODB; 

CREATE TABLE plant_area_xref (
    plant_id INT NOT NULL, 
    area_id INT NOT NULL, 
    sort_idx INT NOT NULL, 
    FOREIGN KEY (plant_id) REFERENCES plant(plant_id) ON DELETE CASCADE, 
    FOREIGN KEY (area_id) REFERENCES area(area_id) ON DELETE CASCADE, 
    PRIMARY KEY (plant_id, area_id, sort_idx)  
) ENGINE=INNODB; 

संपादित करें:

बस जवाब देने के लिए आपका बोनस प्रश्न:

Bonus Question Is it time to step away from MySQL? Is there a better DB to manage this? 

इसका MySQL के साथ कुछ लेना देना नहीं है। यह खराब डेटाबेस डिजाइन के साथ सिर्फ एक मुद्दा था। आपको प्रत्येक आरडीबीएमएस (MySQL, Oracle, MSSQL, PostgreSQL आदि) में इस तरह के मामलों के लिए चौराहे तालिकाओं और कई से अधिक रिश्ते का उपयोग करना चाहिए।

+0

क्या यह sort_idx को याद नहीं करता है? 'plant_id, area_id' अद्वितीय नहीं है, 'area_id/sort_idx' होगा। मुझे इस अनुक्रम को बरकरार रखने में सक्षम होना चाहिए 'क्षेत्र: 1' -> 'पौधों: 2,20,1,2,2,20,1' (उस क्रम में) – Moak

+0

जोड़ा गया sort_idx। plant_id, area_id को अद्वितीय होने की आवश्यकता नहीं है। विशिष्ट प्राथमिकता डबल प्राथमिक कुंजी द्वारा हासिल की जाती है। –

+0

हां, लेकिन मेरा मुद्दा यह है कि क्षेत्र 1 - संयंत्र 2 डबल हो सकता है (उसी संयंत्र में क्षेत्र में दो बार, इसलिए असली विशिष्टता क्षेत्र/sort_index है। मुझे जो चाहिए वह मिला (डबल प्राथमिक) यदि आप इसे बदलते हैं तो यह मैं जवाब स्वीकार कर सकता हूं। – Moak

संबंधित मुद्दे

 संबंधित मुद्दे