2008-10-15 14 views
63

मैं विकास के लिए स्थानीय रूप से एक MySQL डेटाबेस चला रहा हूं, लेकिन पोस्टग्रेज़ का उपयोग करने वाले हेरोकू को तैनात कर रहा हूं। Heroku लगभग सबकुछ संभालता है, लेकिन मेरे मामले-असंवेदनशील बयान की तरह केस संवेदनशील हो जाते हैं। मैं iLike कथन का उपयोग कर सकता था, लेकिन मेरा स्थानीय MySQL डेटाबेस इसे संभाल नहीं सकता है।आप MySQL और Postgres दोनों के लिए केस असंवेदनशील क्वेरी कैसे लिखते हैं?

केस असंवेदनशील क्वेरी लिखने का सबसे अच्छा तरीका क्या है जो MySQL और Postgres दोनों के साथ संगत है? या क्या मुझे डीबी के आधार पर अलग-अलग पसंद और iLike स्टेटमेंट लिखने की ज़रूरत है, मेरा ऐप बात कर रहा है?

+4

यदि आप प्रोड्यूशन में पोस्टग्रेस का उपयोग कर रहे हैं तो पोस्टग्रेज़ स्थानीय रूप से भी उपयोग करें। यह पहला मुद्दा नहीं होगा जिसे आप चलाते हैं, और इसका मतलब यह भी है कि आप पोस्टग्रेस-विशिष्ट कुछ भी नहीं ले सकते हैं। –

उत्तर

57
select * from foo where upper(bar) = upper(?); 

यदि आप कॉलर में ऊपरी मामले में पैरामीटर सेट करते हैं, तो आप दूसरे फ़ंक्शन कॉल से बच सकते हैं।

+11

आप यह भी सुनिश्चित कर सकते हैं कि यह ऊपरी है: जहां अपर (बार) = UPPER (?) –

+2

मैं 100% निश्चित नहीं हूं, लेकिन मेरी यादें यह है कि यह किसी भी इंडेक्स का उपयोग नहीं करेगा जो foo पर मौजूद हो सकता है क्योंकि यह नहीं कर सकता इंडेक्स के खिलाफ फ़ंक्शन के रिटर्न वैल्यू को स्कैन करें। – richo

+5

@Richo: लेकिन यदि आपको इसकी आवश्यकता हो तो आप 'ऊपरी (बार)' में एक इंडेक्स बना सकते हैं: http://www.postgresql.org/docs/current/interactive/sql-createindex.html –

13

postgres में, आप यह कर सकते हैं:

SELECT whatever FROM mytable WHERE something ILIKE 'match this'; 

मैं अगर वहाँ MySQL के लिए एक बराबर है यकीन नहीं है, लेकिन आप हमेशा इस जो थोड़ा बदसूरत है लेकिन दोनों MySQL और postgres में काम करना चाहिए कर सकते हैं :

SELECT whatever FROM mytable WHERE UPPER(something) = UPPER('match this'); 
0

ऊपरी में कनवर्ट करना सबसे अच्छा है क्योंकि इसमें 3 सबसे अधिक उपयोग किए गए रेल डेटाबेस डेटाबेस बैकएंड के लिए संगत वाक्यविन्यास शामिल है। PostgreSQL, MySQL और SQLite सभी इस वाक्यविन्यास का समर्थन करते हैं। इसमें (नाबालिग) दोष है कि आपको अपने आवेदन में या अपनी परिस्थितियों में अपनी खोज स्ट्रिंग को अपरकेस करना है, जिससे इसे थोड़ा उलझन में डाल दिया जा सकता है, लेकिन मुझे लगता है कि आपके द्वारा प्राप्त अनुकूलता इसे लायक बनाती है।

MySQL और SQLite3 दोनों में केस-असंवेदनशील LIKE ऑपरेटर है। केवल PostgreSQL में केस-सेंसिटिव लिके ऑपरेटर और पोस्टग्रेएसक्यूएल-विशिष्ट (मैनुअल प्रति) ILIKE ऑपरेटर केस-असंवेदनशील खोजों के लिए है। आप Rails अनुप्रयोग पर अपनी स्थितियों में LIKE की इलिक्क कीड़े निर्दिष्ट कर सकते हैं, लेकिन ध्यान रखें कि एप्लिकेशन MySQL या SQLite के अंतर्गत काम करना बंद कर देगा।

एक तीसरा विकल्प यह जांचने के लिए हो सकता है कि आप किस डेटाबेस इंजन का उपयोग कर रहे हैं और तदनुसार खोज स्ट्रिंग को संशोधित करें। यह ActiveRecord के कनेक्शन एडेप्टर में/बंदरगाह को हैकिंग करके बेहतर किया जा सकता है और PostgreSQL एडाप्टर क्वेरी निष्पादन से पहले "ILIKE" के लिए "LIKE" को प्रतिस्थापित करने के लिए क्वेरी स्ट्रिंग को संशोधित करता है। यह समाधान हालांकि सबसे अधिक मजबूत और आसान तरीकों के प्रकाश में दोनों शब्दों को अपरकेसिंग करने के लिए है, मुझे लगता है कि यह प्रयास खराब नहीं है (हालांकि आपको इसे करने के लिए बहुत सारे ब्राउनी पॉइंट मिलेंगे)।

+0

मैंने कुछ ऐसा करने के लिए प्लगइन पर काम करना शुरू किया: http://github.com/myronmarston/case_insensitive_attributes यह कहीं भी उत्पादन में उपयोग नहीं किया जाता है , इसलिए भाग न लें और इसे अपने ऐप में इस्तेमाल करें, लेकिन यह एक शुरुआत है। नैतिक बढ़ावा के लिए –

1

आप searchlogic प्लगइन की जांच करने पर भी विचार कर सकते हैं, जो LIKE/ILIKE आपके लिए स्विच करता है।

74

इस कहानी का नैतिक है: विकास और उत्पादन के लिए एक अलग सॉफ़्टवेयर स्टैक का उपयोग न करें। कभी नहीँ।

आप केवल उन बगों के साथ समाप्त हो जाएंगे जिन्हें आप देव में पुन: पेश नहीं कर सकते हैं; आपका परीक्षण बेकार होगा। बस यह मत करो।

एक अलग डेटाबेस इंजन का उपयोग करना सवाल से बाहर है - एफएआर अधिक मामलों में जहां यह अलग-अलग व्यवहार से अलग व्यवहार करेगा (क्या आपने डेटाबेस द्वारा उपयोग में कॉलेशन की जांच की है? क्या वे हर मामले में समान हैं? अगर नहीं, आप वर्कर कॉलम पर ऑर्डर कर सकते हैं)

+4

+1, धन्यवाद। गंभीरता से, हालांकि, यह सही है और किसी भी "प्रश्न का उत्तर दें" उत्तरों से कहीं बेहतर है। हालांकि मैं सामान्य रूप से कहानी के जवाबों के इन नैतिक से नफरत करता हूं, लेकिन इस मामले में यह अच्छी तरह से किया जाता है। –

+3

एआर/एएम का पूरा बिंदु आपको विकास और उत्पादन में विभिन्न डेटाबेस बैक सिरों का उपयोग करने की अनुमति देना है।मेरी राय में, यहां असफल रहा है कि क्वेरी एआर/एएम द्वारा कैसे उत्पन्न की जाती है। –

+0

@ क्रिस्टोफर मौजान: http://www.joelonsoftware.com/articles/LeakyAbstractions.html देखें कि यह एक बुरा विचार क्यों है। – MarkR

2

यदि आप PostgreSQL 8.4 का उपयोग कर रहे हैं तो आप केस असंवेदनशील टेक्स्ट फ़ील्ड बनाने के लिए citext मॉड्यूल का उपयोग कर सकते हैं।

+1

या एक कार्यात्मक सूचकांक जोड़ें: http://www.postgresql.org/docs/7.3/static/indexes-functional.html – troelskn

1

यदि आप किसी ब्लॉक के अंदर एक सबस्ट्रिंग से मेल खाना चाहते हैं तो आप पोस्टग्रेस में ~ * का भी उपयोग कर सकते हैं। ~ मामला केस-संवेदनशील सबस्ट्रिंग, ~ * केस असंवेदनशील सबस्ट्रिंग। यह धीमा ऑपरेशन है, लेकिन मुझे खोजों के लिए यह उपयोगी लगता है।

Select * from table where column ~* 'UnEvEn TeXt'; 
Select * from table where column ~ 'Uneven text'; 

दोनों "कुछ असमान पाठ यहाँ" पर मारते थे केवल पूर्व "कुछ असमान पाठ यहाँ"

36

उपयोग अरेल पर मारते थे:

Author.where(Author.arel_table[:name].matches("%foo%")) 

matchesILIKE ऑपरेटर का उपयोग करेगा Postgres के लिए, और LIKE सब कुछ के लिए।

+2

विश मैं एक से अधिक +1 दे सकता है ... मैं कभी नहीं पता था कि अरेल ऐसा कर सकता है! शायद क्योंकि यह लगभग पूरी तरह से अनियंत्रित है? एचएम ... –

+0

हाँ --- क्या यह कहीं भी दस्तावेज है? बिंदु 2 के लिए – Dogweather

8

कई जवाब, जिनमें से कोई भी बहुत संतोषजनक रहे हैं।

  • कम (बार) = कम MySQL और Postgres परहोगा काम, लेकिन करने के लिए MySQL पर बहुत प्रदर्शन की संभावना है (?): MySQL कम समारोह की वजह से इसकी अनुक्रमणिका का उपयोग नहीं होगा। पोस्टग्रेज़ पर आप एक कार्यात्मक सूचकांक जोड़ सकते हैं (लोअर (बार) पर) लेकिन MySQL इसका समर्थन नहीं करता है।
  • MySQL (जब तक आप केस-संवेदी collation सेट नहीं करते हैं) केस-असंवेदनशील मिलान स्वचालित रूप से करते हैं, और इसकी अनुक्रमणिका का उपयोग करते हैं। (बार =?)।
  • डेटाबेस के बाहर अपने कोड से, बार और bar_lower क्षेत्रों, जहां bar_lower कम (पट्टी) का परिणाम शामिल बनाए रखें। (यह डेटाबेस ट्रिगर्स का उपयोग करके भी संभव हो सकता है)। (Drupal पर इस समाधान की चर्चा देखें)। यह बेकार है लेकिन कम से कम प्रत्येक डेटाबेस पर बहुत कम तरीके से चलता है।
+0

खैर धन्यवाद, मुझे पता चला कि यह वास्तव में केस-संवेदी डिफ़ॉल्ट रूप से है। – ADTC

5

regexp केस संवेदी (बाइनरी के साथ प्रयोग किया है जब तक), और इसलिए की तरह इस्तेमाल किया जा सकता है ...

SELECT id FROM person WHERE name REGEXP 'john'; 

... मैच के लिए 'जॉन', 'जॉन', 'जॉन' , आदि

+0

यह कमाल है! मैं एकाधिक खोजशब्दों के लिए '|' का उपयोग कर सकता हूं। – ADTC

+0

जबकि regexps अत्यंत बहुमुखी हैं, कि वे काफी धीमी गति से कर रहे हैं ध्यान दें और आप बड़े डेटा सेट या धीमी गति से सर्वर पर यह नोटिस करेंगे – aydow

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