PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

क्या PostgreSQL उच्चारण असंवेदनशील कॉलेशन का समर्थन करता है?

अस्पष्ट मॉड्यूल का उपयोग करें उसके लिए - जो आप लिंक कर रहे हैं उससे बिल्कुल अलग है।

<ब्लॉकक्वॉट>

unaccent एक टेक्स्ट सर्च डिक्शनरी है जो लेक्सेम्स से एक्सेंट (डायक्रिटिकसाइन) को हटा देता है।

इसके साथ प्रति डेटाबेस एक बार इंस्टॉल करें:

CREATE EXTENSION unaccent;

अगर आपको कोई त्रुटि मिलती है जैसे:

ERROR: could not open extension control file
"/usr/share/postgresql/<version>/extension/unaccent.control": No such file or directory

इस संबंधित उत्तर में दिए गए निर्देश के अनुसार अपने डेटाबेस सर्वर पर योगदान पैकेज स्थापित करें:

  • PostgreSQL पर बेहिसाब एक्सटेंशन बनाते समय त्रुटि

अन्य बातों के अलावा, यह फ़ंक्शन प्रदान करता है unaccent() आप अपने उदाहरण के साथ उपयोग कर सकते हैं (जहां LIKE लगता है जरूरत नहीं है)।

SELECT *
FROM   users
WHERE  unaccent(name) = unaccent('João');

सूचकांक

उस प्रकार की क्वेरी के लिए किसी अनुक्रमणिका का उपयोग करने के लिए, व्यंजक पर अनुक्रमणिका बनाएँ। हालांकि , Postgres केवल IMMUTABLE . स्वीकार करता है सूचकांक के लिए कार्य। यदि कोई फ़ंक्शन एक ही इनपुट के लिए एक अलग परिणाम लौटा सकता है, तो सूचकांक चुपचाप टूट सकता है।

अस्पष्ट () केवल स्थिर नहीं अपरिवर्तनीय

दुर्भाग्य से, अस्वीकार्य () केवल स्थिर है , नहीं अपरिवर्तनीय . pgsql-bugs पर इस थ्रेड के अनुसार, यह तीन . के कारण है कारण:

  1. यह शब्दकोश के व्यवहार पर निर्भर करता है।
  2. इस शब्दकोश का कोई हार्ड-वायर्ड कनेक्शन नहीं है।
  3. इसलिए यह वर्तमान search_path . पर भी निर्भर करता है , जो आसानी से बदल सकता है।

वेब पर कुछ ट्यूटोरियल केवल फ़ंक्शन की अस्थिरता को IMMUTABLE . में बदलने का निर्देश देते हैं . यह पाशविक बल विधि कुछ शर्तों के तहत टूट सकती है।

अन्य एक सरल अपरिवर्तनीय . का सुझाव देते हैं रैपर फ़ंक्शन (जैसे मैंने खुद को अतीत में किया था)।

इस बात पर बहस चल रही है कि क्या वैरिएंट को दो मापदंडों के साथ बनाया जाए IMMUTABLE जो स्पष्ट रूप से प्रयुक्त शब्दकोश की घोषणा करता है। यहाँ या यहाँ पढ़ें।

एक अन्य विकल्प यह मॉड्यूल होगा IMMUTABLE unaccent() . के साथ Musicbrainz द्वारा कार्य, Github पर प्रदान किया गया। खुद इसका परीक्षण नहीं किया। मुझे लगता है कि मैं एक बेहतर विचार के साथ आया हूं :

अभी के लिए सर्वश्रेष्ठ

यह दृष्टिकोण अधिक कुशल है क्योंकि अन्य समाधान चारों ओर तैरते हैं, और सुरक्षित हैं .
एक अपरिवर्तनीय बनाएं SQL आवरण फ़ंक्शन हार्ड-वायर्ड स्कीमा-योग्य फ़ंक्शन और शब्दकोश के साथ दो-पैरामीटर प्रपत्र निष्पादित करता है।

चूंकि एक गैर-अपरिवर्तनीय फ़ंक्शन को नेस्ट करने से फ़ंक्शन इनलाइनिंग अक्षम हो जाएगी, इसे C-फ़ंक्शन की एक प्रति पर आधारित करें, (नकली) घोषित IMMUTABLE भी। इसका केवल उद्देश्य SQL फ़ंक्शन रैपर में उपयोग किया जाना है। अपने आप इस्तेमाल करने के लिए नहीं है।

परिष्कार की आवश्यकता है क्योंकि सी फ़ंक्शन की घोषणा में शब्दकोश को हार्ड-वायर करने का कोई तरीका नहीं है। (सी कोड को ही हैक करने की आवश्यकता होगी।) SQL रैपर फ़ंक्शन ऐसा करता है और दोनों फ़ंक्शन को और को इनलाइन करने की अनुमति देता है एक्सप्रेशन इंडेक्स.

CREATE OR REPLACE FUNCTION public.immutable_unaccent(regdictionary, text)
  RETURNS text LANGUAGE c IMMUTABLE PARALLEL SAFE STRICT AS
'$libdir/unaccent', 'unaccent_dict';

CREATE OR REPLACE FUNCTION public.f_unaccent(text)
  RETURNS text LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT AS
$func$
SELECT public.immutable_unaccent(regdictionary 'public.unaccent', $1)
$func$;

ड्रॉप पैरेलल सेफ Postgres 9.5 या पुराने के लिए दोनों कार्यों से।

सार्वजनिक स्कीमा होने के नाते जहां आपने एक्सटेंशन इंस्टॉल किया है (सार्वजनिक डिफ़ॉल्ट है)।

स्पष्ट प्रकार की घोषणा (regdictionary ) दुर्भावनापूर्ण उपयोगकर्ताओं द्वारा फ़ंक्शन के अतिभारित रूपों के साथ काल्पनिक हमलों से बचाव करता है।

पहले, मैंने STABLE पर आधारित रैपर फंक्शन की वकालत की थी फ़ंक्शन अस्वीकार्य () बेहिसाब मॉड्यूल के साथ भेज दिया। वह अक्षम फ़ंक्शन इनलाइनिंग। यह संस्करण दस गुना तेज निष्पादित करता है मेरे द्वारा पहले यहां किए गए साधारण रैपर फ़ंक्शन की तुलना में। समारोह के लिए - जब तक मुझे पता नहीं चला कि शब्दकोश स्कीमा-योग्य भी हो सकता है। फिर भी (पोस्टग्रेज 12) दस्तावेज़ीकरण से बहुत स्पष्ट नहीं है।

यदि C फ़ंक्शन बनाने के लिए आपके पास आवश्यक विशेषाधिकारों की कमी है, आप दूसरे सर्वोत्तम कार्यान्वयन पर वापस आ गए हैं:एक IMMUTABLE स्थिर . के चारों ओर फ़ंक्शन रैपर अस्वीकार्य () मॉड्यूल द्वारा प्रदान किया गया कार्य:

CREATE OR REPLACE FUNCTION public.f_unaccent(text)
  RETURNS text AS
$func$
SELECT public.unaccent('public.unaccent', $1)  -- schema-qualify function and dictionary
$func$  LANGUAGE sql IMMUTABLE PARALLEL SAFE STRICT;

अंत में, अभिव्यक्ति अनुक्रमणिका क्वेरी करने के लिए तेज़ :

CREATE INDEX users_unaccent_name_idx ON users(public.f_unaccent(name));

याद रखें अनुक्रमणिकाएं बनाएं फ़ंक्शन या डिक्शनरी में किसी भी बदलाव के बाद इस फ़ंक्शन को शामिल करना, जैसे इन-प्लेस प्रमुख रिलीज़ अपग्रेड जो इंडेक्स को फिर से नहीं बनाएगा। हाल की प्रमुख रिलीज़ में अस्वीकार्य . के सभी अपडेट थे मॉड्यूल।

अनुक्रमणिका से मिलान करने के लिए क्वेरी को अनुकूलित करें (इसलिए क्वेरी प्लानर इसका उपयोग करेगा):

SELECT * FROM users
WHERE  f_unaccent(name) = f_unaccent('João');

आपको सही अभिव्यक्ति में फ़ंक्शन की आवश्यकता नहीं है। वहां आप 'Joao' . जैसे बिना उच्चारण वाले तार भी दे सकते हैं सीधे।

तेज़ फ़ंक्शन अभिव्यक्ति अनुक्रमणिका . का उपयोग करके अधिक तेज़ क्वेरी में अनुवाद नहीं करता है . यह पूर्व-गणना मूल्यों पर संचालित होता है और पहले से ही बहुत तेज है। लेकिन अनुक्रमणिका रखरखाव और क्वेरी जो अनुक्रमणिका लाभ का उपयोग नहीं कर रही हैं।

पोस्टग्रेज 10.3 / 9.6.8 आदि के साथ क्लाइंट प्रोग्राम के लिए सुरक्षा कड़ी कर दी गई है। आपको जरूरत किसी भी अनुक्रमणिका में उपयोग किए जाने पर प्रदर्शित किए गए स्कीमा-योग्यता फ़ंक्शन और शब्दकोश नाम के लिए। देखें:

  • 'टेक्स्ट सर्च डिक्शनरी "अनएक्सेंट" मौजूद नहीं है' पोस्टग्रेज लॉग में प्रविष्टियां, माना जाता है कि स्वचालित विश्लेषण के दौरान

संयुक्ताक्षर

Postgres में 9.5 या पुराने unaccent() के बाद से 'Œ' या 'ß' जैसे संयुक्ताक्षरों को मैन्युअल रूप से विस्तारित करना होगा (यदि आपको इसकी आवश्यकता है) हमेशा एक एकल . को प्रतिस्थापित करता है पत्र:

SELECT unaccent('Œ Æ œ æ ß');

unaccent
----------
E A e a S

Postgres 9.6 . में आपको यह अपडेट पसंद नहीं आएगा :

<ब्लॉकक्वॉट>

योगदान/अस्वीकृति बढ़ाएँ के मानक unaccent.rules यूनिकोड को ज्ञात सभी डायक्रिटिक्स को संभालने के लिए फ़ाइल, और संयुक्ताक्षर का सही ढंग से विस्तार करें (थॉमस मुनरो, लियोनार्ड बेनेडेटी)

बोल्ड जोर मेरा। अब हमें मिलता है:

SELECT unaccent('Œ Æ œ æ ß');

unaccent
----------
OE AE oe ae ss

पैटर्न मिलान

LIKE . के लिए या ILIKE मनमाने पैटर्न के साथ, इसे मॉड्यूल के साथ संयोजित करें pg_trgm PostgreSQL 9.1 या बाद में। एक ट्रिगर GIN (आमतौर पर बेहतर) या GIST एक्सप्रेशन इंडेक्स बनाएं। GIN के लिए उदाहरण:

CREATE INDEX users_unaccent_name_trgm_idx ON users
USING gin (f_unaccent(name) gin_trgm_ops);

जैसे प्रश्नों के लिए इस्तेमाल किया जा सकता है:

SELECT * FROM users
WHERE  f_unaccent(name) LIKE ('%' || f_unaccent('João') || '%');

सादे btree की तुलना में GIN और GIST इंडेक्स को बनाए रखना अधिक महंगा है:

  • जीआईएसटी और जीआईएन इंडेक्स के बीच अंतर

केवल बाएं-एंकर वाले पैटर्न के लिए सरल समाधान हैं। पैटर्न मिलान और प्रदर्शन के बारे में अधिक जानकारी:

  • PostgreSQL में LIKE, SIMILAR TO या रेगुलर एक्सप्रेशन से मिलान करने वाला पैटर्न

pg_trgm "समानता" के लिए उपयोगी ऑपरेटर भी प्रदान करता है (% ) और "दूरी" (<-> )।

ट्रिग्राम इंडेक्स ~ . के साथ सरल रेगुलर एक्सप्रेशन का भी समर्थन करते हैं और अन्य। और केस असंवेदनशील ILIKE . से मेल खाने वाला पैटर्न :

  • PostgreSQL एक्सेंट + केस असंवेदनशील खोज


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PostgreSQL पर रिलीज टेस्ट को तेज करने के लिए ऑटोमेशन का उपयोग करना

  2. PostgreSQL में निम्न-स्तरीय संसाधन पूलिंग के बारे में कुछ विचार

  3. PostgreSQL में एकाधिक कॉलम कैसे अपडेट करें

  4. Postgres . में मौजूदा कॉलम में 'धारावाहिक' जोड़ना

  5. कैसे अद्वितीय संयुक्त प्राथमिक कुंजी के साथ एक Postgres तालिका बनाने के लिए?