अंतरराष्ट्रीय डेटाबेस के लिए एक कॉलेशन कैसे चुनें?


22

मैं एक डेटाबेस डिजाइन कर रहा हूं जो विभिन्न भाषाओं में डेटा संग्रहीत करेगा (UTF-8 का उपयोग करके), इसलिए मुझे लगता है कि क्वेरी के परिणामों को प्रदर्शित करने का सबसे अच्छा तरीका यह क्वेरी के दौरान उपयोगकर्ता की भाषा के अनुसार आदेश दे रहा है ( क्योंकि एक से अधिक हैं इस तरह से सही तरीके से ),

SELECT a < b COLLATE "de_DE" FROM test1;

यह मानते हुए कि अंतर्राष्ट्रीय डेटा के साथ काम करने का यह सही तरीका है, जो डेटाबेस के लिए सबसे अच्छा टकराव है? PostgreSQL प्रलेखन कहता है :

C और POSIX टकराव दोनों "पारंपरिक C" व्यवहार को निर्दिष्ट करते हैं, जिसमें "Z" के माध्यम से केवल ASCII अक्षर "A" को अक्षर के रूप में माना जाता है, और वर्ण कोड बाइट मानों के अनुसार कड़ाई से किया जाता है।

मुझे लगता है कि इस मामले में यह सबसे अच्छा विकल्प है, या मैं गलत हूं?

(बोनस प्रश्न: क्या क्वेरी में ही कोलाज का चयन करना बहुत धीमा है?)।


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

2
स्रोत उद्धृत करते समय, एक लिंक जोड़ें।
इरविन ब्रान्डेसटेटर

जवाबों:


27

Cमिलान सही विकल्प है।

लोकेल के बिना सब कुछ थोड़ा तेज है। और चूँकि कोई भी टकराव वैसे भी सही नहीं है, डेटाबेस को बिना टकराव के बनाएँ , जिसका अर्थ है C

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

ध्यान रखें कि Postgres अंतर्निहित OS द्वारा प्रदान की गई लोकेल सेटिंग्स पर बनाता है, इसलिए आपको उपयोग किए जाने वाले प्रत्येक लोकेल के लिए उत्पन्न होने वाले स्थानों की आवश्यकता होती है। इतने पर संबंधित जवाब में अधिक यहाँ और यहाँ

हालांकि, जैसा कि @Craig पहले से ही उल्लेख किया गया है , सूचकांक इस परिदृश्य में अड़चन हैं। सूचकांक के टकराव को कई मामलों में लागू ऑपरेटर के टकराव से मेल खाना पड़ता है जिसमें चरित्र डेटा शामिल होता है।

आप COLLATEअनुक्रमित में विनिर्देशक का उपयोग मिलान अनुक्रमणिका बनाने के लिए कर सकते हैं । यदि आप एक ही तालिका में डेटा मिला रहे हैं, तो आंशिक अनुक्रमणिका सही विकल्प हो सकती है।

उदाहरण के लिए, अंतर्राष्ट्रीय तार वाली एक तालिका:

CREATE TABLE string (
   string_id serial
  ,lang_id   int NOT NULL
  ,string    text NOT NULL
);

और आप ज्यादातर एक समय में एक भाषा में रुचि रखते हैं:

SELECT *
FROM   string
WHERE  lang_id = 5  -- 5 being German / Germany here
AND    string > 'foo' COLLATE "de_DE"
ORDER  BY string COLLATE "de_DE";

फिर आंशिक सूचकांक बनाएं जैसे:

CREATE INDEX string_string_lang_id_idx ON string (string COLLATE "de_DE")
WHERE lang_id = 5;

आपकी ज़रूरत की प्रत्येक भाषा के लिए एक

वास्तव में, विरासत इस तरह से एक मेज के लिए एक बेहतर दृष्टिकोण हो सकता है। तब आपके पास प्रत्येक विरासत वाली मेज पर एक सादा सूचकांक हो सकता है जिसमें केवल एक ही स्थान के लिए तार होते हैं। आपको निश्चित रूप से विरासत में मिली तालिकाओं के लिए विशेष नियमों के साथ सहज होने की आवश्यकता है।


1
क्या आप किसी नए डेटाबेस के लिए डिफ़ॉल्ट रूप से सी लोकेल (या 'गैर लोकेल' का सटीक होना) का उपयोग करते हैं?
जैक डगलस

1
@JackDouglas: नहीं, मैं केवल विशेष मामलों के लिए ही करूंगा। आमतौर पर यह जगह पर आम तौर पर इस्तेमाल किए जाने वाले लोकेल के साथ काम करने के लिए बहुत अधिक व्यावहारिक है।
इरविन ब्रान्डेसटेटर

13

मेरा सुझाव है कि आप एक कोलाज चुनें जो डिफ़ॉल्ट यूनिकोड ऑर्डर प्रदान करता है। इस तरह, यदि आप प्रत्येक क्वेरी में कोलाज को ओवरराइड नहीं करते हैं तो भी आपको परिणाम मिलते हैं। दुर्भाग्य से, अधिकांश (सभी?) ऑपरेटिंग सिस्टम एक लोकेल प्रदान नहीं करते हैं जिसे बस "डिफ़ॉल्ट यूनिकोड" या ऐसा कुछ नाम दिया गया है, इसलिए आपको एक अच्छा विकल्प का अनुमान लगाना होगा और / या शोध करना होगा। उदाहरण के लिए, Linux / glibc पर, de_DE.utf8 या en_US.utf8 स्थान केवल डिफ़ॉल्ट व्यवहार से गुजरते हैं, इसलिए दोनों अच्छे विकल्प हैं।

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

(किसी क्वेरी में टकराव को ओवरराइड करने से बहुत अधिक ओवरहेड नहीं होता है। यह केवल एक पार्स-टाइम ऑपरेशन है।)


शायद कम दर्द एक
पागल

1
वर्तमान में मैं एक परीक्षण डेटाबेस में es_CL.utf8 का उपयोग कर रहा हूं, लेकिन आपके उत्तर के लिए धन्यवाद मैंने थोड़ा और अधिक देखा और पाया कि utf8_unicode_ciजाने का रास्ता है
ताई

0

हम एक डॉकटर कंटेनर में पोस्टग्रेज का उपयोग करते हैं, इस प्रकार हमारे पास हमेशा आईसीयू उपलब्ध होता है और und-x-icuडिफ़ॉल्ट रूप में उपयोग होता है ।

अध्याय 23.2.2.2.2 में इसका उल्लेख है पोस्टर्स डॉक्स उल्लेखों के ICU टकराव:

und-x-icu ("अपरिभाषित" के लिए)
ICU "रूट" कॉलेशन। एक उचित भाषा-अज्ञेय क्रम क्रम प्राप्त करने के लिए इसका उपयोग करें।

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