2016-12-05 9 views
13

मैं एक चौराहे पर हूं कि यह तय करना कि टैग उनके स्वयं के संसाधन या नोट की घोंसला वाली संपत्ति होनी चाहिए या नहीं। यह सवाल रीस्टफुल डिज़ाइन और डेटाबेस स्टोरेज पर थोड़ा सा स्पर्श करता है।क्या टैग का अपना संसाधन होना चाहिए या घोंसला वाली संपत्ति होनी चाहिए?

संदर्भ: मेरे पास एक नोट संसाधन है। उपयोगकर्ताओं के पास कई नोट्स हो सकते हैं। प्रत्येक नोट में कई टैग हो सकते हैं।

कार्यात्मक लक्ष्य: मैं निम्न करने के लिए रूट बनाने के लिए की जरूरत है:
1) लायें सभी उपयोगकर्ता टैग। कुछ ऐसा: GET /users/:id/tags
2) किसी नोट से जुड़े टैग हटाएं।
3) एक विशिष्ट नोट में टैग जोड़ें।

डेटा/प्रदर्शन लक्ष्य
1) उपयोगकर्ता टैग लाई जा रही है तेजी से होना चाहिए। यह "autosuggest"/"स्वतः पूर्ण" के उद्देश्य के लिए है।
2) डुप्लिकेट को रोकें (जितना संभव हो सके)। मैं चाहता हूं टैग टैग द्वारा डेटा पूछने में सक्षम होने के उद्देश्य से जितना संभव हो सके पुन: उपयोग किया जाए। उदाहरण के लिए, मैं उन परिदृश्यों को कम करना चाहता हूं जहां उपयोगकर्ता "सुपरहीरो" जैसे टैग टाइप करते हैं, जब टैग "सुपरहीरो" पहले से मौजूद है। नेस्ट संपत्ति के रूप में

1) टैग:

कहा जा रहा है, जिस तरह से मैं इसे देख, वहाँ एक टिप्पणी संसाधन पर टैग भंडारण के दो दृष्टिकोण हैं। उदाहरण के लिए:

type: 'notes', 
attributes: { 
    id: '123456789', 
    body: '...', 
    tags: ['batman', 'superhero'] 
} 

2) टैग अपने संसाधन के रूप में।

type: 'notes', 
data: { 
    id: '123456789', 
    body: '...', 
    tags: [1,2,3] // <= Tag IDs instead of strings 
} 

या तो तरीकों में से एक के ऊपर काम कर सकता था, लेकिन मैं एक समाधान है कि scalability और डेटा स्थिरता (एक लाख नोट और एक करोड़ टैग की कल्पना) की अनुमति देगा रहा हूँ: उदाहरण के लिए। इस बिंदु पर, मैं विकल्प # 1 की ओर झुका रहा हूं क्योंकि कोड के साथ सामना करना आसान है लेकिन यह सही विकल्प नहीं हो सकता है।

मुझे विभिन्न दृष्टिकोणों के बारे में कुछ विचार सुनने में बहुत दिलचस्पी है, खासकर जब से मुझे इस विषय के बारे में SO पर समान प्रश्न नहीं मिल रहे हैं।

अद्यतन उत्तर के लिए धन्यवाद। मेरे लिए सबसे महत्वपूर्ण चीजों में से एक यह पहचान रहा है कि एक दूसरे का उपयोग क्यों फायदेमंद है। मैं कुछ समर्थक/कॉन सूची शामिल करने का उत्तर देना चाहता हूं।

+0

उपयोग करने के लिए आप इस बारे में बात कर रहे हैं, जबकि डीबी में भंडारण टैग करेगा नहीं है या जब आउटपुट बाकी से वापस आ जाता है? –

+0

क्या किसी टैग के नाम और शायद एक आईडी के अलावा कोई अन्य जानकारी है? –

+0

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

उत्तर

6

tl; डॉ

अपनी आवश्यकताओं को ध्यान में रखते हुए, IMO आप tags संसाधनों के रूप में संग्रहीत करना चाहिए और अपने एपीआई एम्बेडेड गुण के रूप में टैग के साथ notes लौटना चाहिए।


डाटाबेस डिजाइन

notes और tags अलग संग्रह (या टेबल) के रूप में रखें। चूंकि आपके पास कई नोट्स और कई टैग हैं और इस तथ्य पर विचार करते हुए कि कोर कार्यक्षमता इन tags पर खोज/स्वत: पूर्ण पर निर्भर है, यह विशेष रूप से tags के लिए notes खोजते समय प्रदर्शन में सुधार करेगी।

नोटों

{ 
    'id': 101, // noteid 
    'title': 'Note title', 
    'body': 'Some note', 
    'tags': ['tag1', 'tag2', ...] 
} 

टैग

{ 
    'id': 'tag1', // tagid 
    'name': 'batman', 
    'description': 'the dark knight', 
    'related': ['tagx', 'tagy', ...], 
    'notes': [101, 103, ...] 
} 

आप related संपत्ति समान tags द्वारा tagx, tagy की जगह आधार पर डुप्लीकेट को संभालने के लिए उपयोग कर सकते हैं: की तरह एक बहुत ही बुनियादी डिजाइन देख सकते हैं।


एपीआई डिजाइन

1. ला रहा है notesuser के लिए:

GET /users/{userid}/notes 

एम्बेड notes वस्तु जब आप बैकएंड में इस मार्ग को संभालने के भीतर tagsuser के लिए

{ 
    'id': 101, 
    'title': 'Note title', 
    'body': 'Some note', 
    'tags': ['batman'] // replacing the tag1 by its name from tag collection 
} 

2. ला रहा है tags: notes वस्तु अपने एपीआई भेजने कुछ इस तरह देखना चाहिए

GET /users/{userid}/tags 

तो यह आवश्यक नहीं है, तो आप notes संपत्ति जिसमें भेजने पर छोड़ सकते हैं आपके notes के लिए id

3।notes के लिए tags हटाना:

DELETE /users/{userid}/{noteid}/{tag} 

4. notes के लिए tags जोड़ना:

PUT /users/{userid}/{noteid}/{tag} 

निष्पादन के मुद्दे को संबोधित करते हुए user के लिए tags प्राप्त करने में कठिनाई है क्योंकि आप एक ही के लिए एक अलग संग्रह है तेजी से होना चाहिए । साथ ही, डुप्लिकेट को संभालना आसान होगा क्योंकि आप related सरणी में समान tags (id या name) जोड़ सकते हैं। उम्मीद है कि यह सहायक था।


क्यों नेस्ट संपत्ति

  • डिजाइन पिछले मामले के रूप में के रूप में स्केलेबल नहीं है के रूप में टैग रखने के लिए नहीं। यदि tags घोंसला वाली संपत्ति है और tag संपादित किया जाना है या कुछ जानकारी को जोड़ना है, तो इसे notes में परिवर्तन की आवश्यकता होगी क्योंकि कई notes में tag हो सकता है। जबकि, संसाधनों के रूप में tags को रखते हुए, उसी notes को उनके ids के साथ मैप किया जाएगा और tags संग्रह/तालिका में एक ही बदलाव की आवश्यकता होगी।

  • डुप्लिकेट tags हैंडलिंग को उतना आसान नहीं हो सकता है जब उन्हें अलग संसाधनों के रूप में रखा जाए।

  • tags के लिए खोज करते समय आपको note के अंदर एम्बेडेड सभी tags खोजना होगा। यह ओवरहेड जोड़ता है।


tags का उपयोग कर के रूप में नेस्ट संपत्ति IMO यह जिससे आप किसी विशिष्ट note के लिए tags जोड़ने या हटाने के बनाती हूँ है की केवल लाभ।

+0

ध्यान दें कि आपके अंतर्निहित डेटाबेस के आधार पर, आप एक [सहयोगी तालिका] (https://en.m.wikipedia.org/wiki/Associative_entity) चाह सकते हैं। –

+0

एक चीज़ जो मैं आपके उत्तर में नहीं देख रहा हूं वह एक दूसरे पर एक दृष्टिकोण चुनने का एक कारण है। मुझे अलग संसाधन के रूप में टैग का इलाज क्यों करना चाहिए? –

+0

मैंने 'टैग' को संपत्ति के रूप में उपयोग करने के लिए कुछ और अंक जोड़े हैं। उम्मीद है कि अब यह और अधिक समझ में आता है। –

2

यह थोड़ा जटिल हो सकता है। इसलिए मैं अपने अनुभव को Tag काम के साथ साझा कर सकता हूं (हमारे मामले में, यह वीओआईपी ऐप की मुख्य विशेषता थी)।

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

type: 'notes', 
data: { 
    id: '123456789', 
    body: '...', 
    tags: [UUID1,UUID2,UUID3] 
} 

बस उदाहरण के लिए, आपको कितनी जानकारी चाहिए। जब आप टैग दर के आधार पर टैग, या आकार का रंग बदलना चाहते हैं, संख्या उपयोग के आधार पर रंग, लिंक (समान नहीं), डुप्लिकेट आदि।

type: 'tag', 
data: { 
    uuid: '234-se-324', 
    body: 'superhero', 
    linked: [UUID3, UUID4] 
    rate: 4.6, 
    usage: 4323 
    duplicate: [superheros, suppahero] 
} 

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

और आपको लगता है कि यह "ऑटोसॉइज" या "स्वतः पूर्ण" के लिए बहुत सारी जानकारी है, लेकिन हमें कभी भी प्रदर्शन के मुद्दों का सामना नहीं करना पड़ा (यदि, यदि सेवर साइड सपोर्ट सैनिटी)। और इस मामले में हर उपयोग के लिए सभी जानकारी महत्वपूर्ण है, और Note भी।

+0

उत्तर के लिए धन्यवाद। एक बात जो मैं आपके उत्तर में नहीं देख रहा हूं वह एक दूसरे पर एक दृष्टिकोण चुनने का एक कारण है। मुझे अलग संसाधन के रूप में टैग का इलाज क्यों करना चाहिए? –

1

नेस्टेड संपत्ति के रूप में टैग सहेजना समझ में आता है यदि आप एक ही पंक्ति में सभी डेटा चाहते हैं। मैं आपको एक उदाहरण देता हूं।

आप आइटम जोड़ने के चालान में,

शीर्षक, विवरण, मूल्य, मात्रा, कर, ...

इस मामले में

कर हो सकता है: वैट 20% तो आप 20% के साथ चालान calcualte, लेकिन एक दिन कर 22% तक बदल जाता है और डीबी पर सहेजे गए सभी चालान 2% अधिक होंगे। इस मामले में आप नया कॉलम जोड़ते हैं और आप इसे कच्चे नंबर 20 के रूप में सहेजते हैं, और जब आप डीबी से उस चालान को पढ़ते हैं तो आपको अलग-अलग तालिकाओं या चर से इसकी गणना करने के बजाय, एक पंक्ति से सभी डेटा प्राप्त होते हैं।

वही बात टैग के साथ है। यदि आप किसी भी तरह डुप्लिकेट मर्ज करना चाहते हैं, तो तारों की बजाय आईडी के साथ इसे करना आसान है।

इसके अलावा कुछ अन्य कारक भी हैं जिन पर आप इसे विचार कर सकते हैं।

सोशल नेटवर्क में, उपयोगकर्ता के पास ऐसे टैग हो सकते हैं जिन्हें कौशल, रुचियां, खेल और बहुत कुछ कहा जाता है।से (https://github.com/mbleigh/acts-as-taggable-on)

टैग के बीच अंतर करने के लिए कोई वास्तविक रास्ता तो अगर आप टैग कर रहे हैं कि आप बहुत सी बातें आप आईडी

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