পোস্টগ্রিএসকিউএল: কীভাবে "কেস-সংবেদনশীল" কোয়েরি তৈরি করবেন


338

পোস্টগ্রেএসকিউএল-তে সংবেদনশীল প্রশ্নগুলি লেখার কোনও উপায় আছে কি না, উদাহরণস্বরূপ আমি চাই যে নিম্নলিখিত 3 টি প্রশ্নের একই ফলাফল ফিরে আসে same

SELECT id FROM groups where name='administrator'

SELECT id FROM groups where name='ADMINISTRATOR'

SELECT id FROM groups where name='Administrator'

যদি সাইটেক্সট আপনার পোস্টগ্রিস ইনস্টলেশন নিয়ে আসে, সাইটেক্সট প্রকার চেষ্টা করুন। এটি কেস-সংবেদনশীল পাঠ্য
মাইকেল বুয়েন

2
এই প্রশ্নের আগতদের জন্য, অফিসিয়াল পোস্টগ্রিজ ডকুমেন্টেশনের এই লিঙ্কটিতে এখানে দেওয়া সমস্ত উত্তর রয়েছে, পাশাপাশি আরও কয়েকটি বিকল্প রয়েছে।
পার্থিয়ান শট

স্যার @ অরুন দ্বারা তৈরি করা উত্তরটি পুনরায় স্বাক্ষর করুন দয়া করে। এটি অনেক কম জটিল এবং প্রয়োগের পরে অনেকগুলি ঝামেলা টানবেন না।
জেলিবোবা

উত্তর:


451

তুলনা করার আগে স্ট্রিংগুলি লোয়ার কেসে রূপান্তর করতে LOWER ফাংশন ব্যবহার করুন ।

এটা চেষ্টা কর:

SELECT id 
  FROM groups
 WHERE LOWER(name)=LOWER('Administrator')

92
এটি লক্ষণীয় গুরুত্বপূর্ণ যে ভবিষ্যদ্বাণীপূর্ণ কলামগুলিতে LOWER (বা কোনও ফাংশন) ব্যবহার করা - এই ক্ষেত্রে "নাম" - এর ফলে কোনও সূচি আর সন্ধানযোগ্য হবে না। এটি যদি একটি বৃহত বা ঘন ঘন জিজ্ঞাসিত সারণী হয় তবে এটি সমস্যার কারণ হতে পারে। কেস-সংবেদনশীল কোলেশন, সিটেক্সট বা কোনও ফাংশন-ভিত্তিক সূচক কর্মক্ষমতা উন্নত করবে।
জর্ডান

108
বা কেবল এই জাতীয় সূচক তৈরি করুন: আইডিএক্সএক্স আইডিএক্স_গোষ্ঠী_নাম গ্রুপগুলি নিম্নে (নাম) তৈরি করুন;
ড্যানিয়েল

19
এছাড়াও varchar_pattern_opsযদি আপনি সূচকটি LIKE 'xxx%'ক্যোয়ারির সাথে কাজ করতে চান তবে নির্দিষ্ট করুন CREATE INDEX ix_groups_name ON groups (lower(name) varchar_pattern_ops)
সায়েপ

10
ILIKE অপারেটরটি (নীচের অন্যান্য উত্তরে যেমন দেখানো হয়েছে) ব্যবহার করা একটি সহজ পদ্ধতির, যদিও এটি সর্বাধিক ভোট দেওয়া উত্তর।
রায়ান

5
এখানে মন্তব্যগুলির মধ্য দিয়ে যাওয়া, এখানে প্রচুর পরামর্শ প্রস্তাব দেয় ILIKE, এটি কার্যকর হবে but with slow response,। গণনার ফলাফলের ভিত্তিতে টেবিলগুলিতে দ্রুত অ্যাক্সেস পেতে, আমি পরামর্শ দিচ্ছি যে কেবলমাত্র এটি যাচাই করা উচিত গ্রহণযোগ্য উত্তরের সাথে যাওয়া উচিত। এখানে এবং এখানে
আফলাবি ওলাওলুয়া আকিনওয়ুমি

230

ILIKEপরিবর্তে ব্যবহারLIKE

SELECT id FROM groups WHERE name ILIKE 'Administrator'

1
দ্রষ্টব্য যে ILIKEস্প্রিং বুটে ব্যবহার করার সময় হাইবারনেট দ্বারা সমর্থিত নয়।
এএনটি

@ এটি এর সাথে কাজ করে org.hibernate.dialect.PostgreSQL94Dialectএবং স্প্রিং বুট ২.০...আরলে। কিন্তু ইন্টেলিজ এটি সম্পর্কে অভিযোগ করে।
সম্মিতা কাব্যেশ

134

সর্বাধিক প্রচলিত পদ্ধতি হ'ল অনুসন্ধান স্ট্রিং এবং ডেটা হয় ছোট হাতের বা বড় হাতের অক্ষর। তবে তা নিয়ে দুটি সমস্যা রয়েছে।

  1. এটি ইংরেজিতে কাজ করে তবে সমস্ত ভাষায় নয়। (বেশিরভাগ ভাষায়ও হতে পারে না)) প্রতিটি ছোট হাতের অক্ষরের সাথে একটি বড় বড় অক্ষর থাকে না; প্রতিটি বড় হাতের অক্ষরের সাথে একটি ছোট ছোট অক্ষর থাকে না।
  2. লোয়ার () এবং উপরের () এর মতো ফাংশন ব্যবহার করা আপনাকে একটি ক্রমিক স্ক্যান দেয়। এটি সূচকগুলি ব্যবহার করতে পারে না। আমার পরীক্ষার সিস্টেমে, নিম্ন () ব্যবহার করা কোনও সূচক ব্যবহার করতে পারে এমন প্রশ্নের চেয়ে 2000 গুণ বেশি সময় নেয় use (পরীক্ষার ডেটাতে 100k এর বেশি সারি রয়েছে))

কমপক্ষে তিনটি কম ঘন ঘন ব্যবহৃত সমাধান রয়েছে যা আরও কার্যকর হতে পারে।

  1. সাইটেক্সট মডিউলটি ব্যবহার করুন , যা বেশিরভাগ ক্ষেত্রে ক্ষেত্রে-সংবেদনশীল ডেটা ধরণের আচরণ অনুকরণ করে। সেই মডিউলটি লোড করে, আপনি কেস-সংবেদনশীল সূচক তৈরি করতে পারেন CREATE INDEX ON groups (name::citext);। (তবে নীচে দেখুন।)
  2. কেস-সংবেদনশীল কোলেশন ব্যবহার করুন। আপনি কোনও ডাটাবেস সূচনা করার সময় এটি সেট করা হয়। কেস-সংবেদনশীল কোলেশন ব্যবহার করার অর্থ আপনি ক্লায়েন্ট কোড থেকে যে কোনও বিন্যাস সম্পর্কে মেনে নিতে পারেন এবং আপনি এখনও কার্যকর ফলাফলগুলি ফিরিয়ে আনতে পারেন। (এর অর্থ হ'ল আপনি কেস-সংবেদনশীল প্রশ্নগুলি করতে পারবেন না Du ডু।)
  3. একটি কার্যকরী সূচক তৈরি করুন। ব্যবহার করে একটি ছোট হাতের সূচক তৈরি করুন CREATE INDEX ON groups (LOWER(name));। কাজ রয়ে, আপনি সূচক সুবিধা গ্রহণ করতে পারেন প্রশ্নের মতো SELECT id FROM groups WHERE LOWER(name) = LOWER('ADMINISTRATOR');, অথবা SELECT id FROM groups WHERE LOWER(name) = 'administrator';যা শুরু করেছো স্মরণ যদিও, নিম্ন () ব্যবহার করতে।

সাইটেক্সট মডিউলটি সত্যিকারের কেস-সংবেদনশীল ডেটা প্রকার সরবরাহ করে না। পরিবর্তে, এটি এমন আচরণ করে যে প্রতিটি স্ট্রিংকে নিম্নতর করা হয়েছে। এটি, এটি এমন আচরণ করে যে আপনি lower()উপরের 3 নম্বরের মতো প্রতিটি স্ট্রিংয়ে ডেকেছেন । সুবিধাটি হ'ল প্রোগ্রামারদের ছোট স্ট্রিংগুলি মনে রাখতে হবে না। তবে আপনাকে সাইটেক্সট ব্যবহার করার সিদ্ধান্ত নেওয়ার আগে ডক্সে আপনার "স্ট্রিং তুলনা আচরণ" এবং "সীমাবদ্ধতা" বিভাগগুলি পড়তে হবে।


1
প্রায় # 1: এটি কোনও সমস্যা হওয়া উচিত নয়, যেহেতু এটি দুটি পৃথক স্ট্রিং হবে (এটি করার col = 'a'এবং করার মতো ভাবেন col = 'b')। প্রায় # 2: যেমনটি আপনি বলেছেন, আপনি একটি অভিব্যক্তিতে একটি সূচক তৈরি করতে পারেন, সুতরাং এটি আসলে সমস্যা নয়। তবে আমি আপনার সাথে একমত যে কোলেশন পরিবর্তন করা সম্ভবত সবচেয়ে ভাল সমাধান।
ভিনসেন্ট সাভার্ড

5
কেউ আমাকে বলতে পারেন যে পোস্টগ্রিসএসকিউএল অন্তর্নির্মিত কোলেশনগুলি কী-সংবেদনশীল কোলেশন? আমি এটিকে বিকল্প হিসাবে দেখছি কিন্তু নেট-এ পোস্টগ্রিসের ক্ষেত্রে সংবেদন-সংবেদনশীল কোলেশন সম্পর্কে কিছুই খুঁজে পাচ্ছি না?
খোরওয়াত

1
@ আনুপশাহ: না, আমি এটি বলছি না। আমি উইন্ডোজে পোস্টগ্রিজ এসকিউএল চালাচ্ছি না। 9.4 ডক্স এটি বলে : "সমস্ত প্ল্যাটফর্মে, ডিফল্ট, সি এবং পসিক্স নামে পরিচিতিগুলি উপলব্ধ। পোস্টগ্রিএসকিউএল মনে করে কোন কোলেশনগুলির সাথে এটি উপলব্ধ select * from pg_collation;
মাইক শেরিল 'ক্যাট রিক্যাল'

1
@ ম্যাথিউ: আমি যে বিষয় সম্পর্কে জানি সেটির এটি সর্বোত্তম ভূমিকা (এবং সতর্কতা): এজ কেসস অব মাইন্ডে রাখার জন্য। পর্ব 1 - পাঠ্য
মাইক শেরিল 'ক্যাট রিকল'


95

আপনি ব্যবহার করতে পারেন ILIKE। অর্থাত

SELECT id FROM groups where name ILIKE 'administrator'

এটি সঠিক এবং আমার জন্য কাজ করে আমি ম্যাক ওএস এক্স (মাউন্টেন লায়ন) ব্যবহার করছি।
এডিজে

5
এটি কার্যকর হবে, তবে ধীর সাড়া দিয়ে। গণনার ফলাফলের ভিত্তিতে সারণিতে দ্রুত অ্যাক্সেস পেতে, আমি lowerফাংশনটি ব্যবহার করার পরামর্শ দিই । আরও বিশদটি
আফোলাবি ওলাওলুয়া আকিনওয়ুমি

1
@ আফোলবি ওলাওলুয়াআকিনউমি প্রাথমিকভাবে এটি আপনার পরিচিত ফলাফলগুলিকে ফিল্টার করার বিরোধী ফলাফলগুলি অনুসন্ধান করছেন কিনা তা নীচে নেমে আসে । পরবর্তী ক্ষেত্রে, সমতা অপারেটরকে কাজ করার সুযোগ করে দেওয়ার জন্য ডেটা স্তরে একটি একক ইউনিফর্মের কেস বহাল রাখা উচিত। [ব্যক্তিগত প্রস্তাবনা টাইপ কোড মানগুলির জন্য উচ্চতর পাস্কেল কেস]
ক্রিস মেরিসিক

53

আপনি ILIKEকীওয়ার্ডটি পড়তে পারেন । এটি এসকিউএল স্ট্যান্ডার্ডের সাথে সঙ্গতিপূর্ণ না হলেও এটি বেশিরভাগ সময়ে কার্যকর হতে পারে। আরও তথ্যের জন্য এখানে দেখুন: http://www.postgresql.org/docs/9.2/static/function-matching.html


9
এখানে নজর রাখার মতো কিছু হ'ল দূষিত ব্যবহারকারী ইনপুট। আপনি যদি কোনও কোয়েরি চালনা করেন email ILIKE 'user-input-email-here'তবে ব্যবহারকারীর ইনপুটটি এড়িয়ে যাওয়ার বিষয়টি নিশ্চিত করুন। অন্যথায় লোকেরা যে কোনও কিছুর সাথে মেলে এমন% এর মতো অক্ষর প্রবেশ করতে পারে।
ম্যাট দে লিওন

2
নিবন্ধন করুন ভাল বলেছ. তবে আমি কেবল আপনাকে জিজ্ঞাসা করতে চাই, যদি আমি এটি ব্যবহার করি ILIKEএবং এটি prepared statementsকি আমাকে রক্ষা করবে sql injection?
slevin

নিশ্চিত নয়, আমি মনে করি আপনি প্রস্তুত বিবৃতিতে একটি পালানোর স্ট্রিং প্রেরণ করতে চান।
ম্যাট দে লিওন

1
"সক্রিয় লোকেল অনুসারে ম্যাচ কেস-সংবেদনশীল করতে LIKE এর পরিবর্তে IliKE কী শব্দটি ব্যবহার করা যেতে পারে This এটি এসকিউএল স্ট্যান্ডার্ডে নয় তবে পোস্টগ্রিসকিউএল এক্সটেনশন" " 9.3
মনোযোগের

1
IliKE তুলনায় ধীর lower(column_name) like %expression%
প্যাট্রিক ইমোসা

28

আপনি যেমন পসিক্স নিয়মিত এক্সপ্রেশনও ব্যবহার করতে পারেন

SELECT id FROM groups where name ~* 'administrator'

SELECT 'asd' ~* 'AsD' আয় t


1
আমার একই সমস্যা ছিল, আমার আমার পোস্টগ্রিজ এসকিউএল ডাটাবেসে সংবেদনশীল অনুসন্ধান দরকার। আমি ব্যবহারকারীর ইনপুট স্ট্রিংটিকে একটি নিয়মিত অভিব্যক্তিতে রূপান্তর করার বিষয়ে ভেবেছিলাম। এখন, = বা LIKE এর পরিবর্তে ~ * ব্যবহার করে পুরোপুরি কাজ করেছে! আমার নতুন সূচি, কলাম বা যা কিছু তৈরি করার দরকার নেই। অবশ্যই, রেজেক্স অনুসন্ধান সোজা বাইট তুলনা তুলনায় ধীর, তবে আমি মনে করি না যে পারফরম্যান্সের উপর প্রভাব দুটি সেট হ্যান্ডেল করার চেয়ে বেশি বেশি হবে (একটি কেবল অনুসন্ধানের জন্য নিম্ন বা বড় হাতের অক্ষরে, তারপরে সংশ্লিষ্ট মূলটি পুনরুদ্ধার করতে হবে) অন্য সেট থেকে ডেটা)। তা ছাড়া এই ক্লিনার!
সাইবারকনাইট

1
ভাল, তবে উদাহরণস্বরূপ regexp_matches () এর সাথে কী করবেন?
WKT

পোস্টগ্র্যাস ডক্স অনুসারে: অপারেটর I লাইকের সমতুল্য, এবং ~~ * ILIKE এর সাথে মিলে যায়। এছাড়াও! ~~ এবং! ~~ * অপারেটরগুলি যথাক্রমে পছন্দ না এবং পছন্দ নয় প্রতিনিধিত্ব করে। এই অপারেটরগুলির সকলই পোস্টগ্রিজ এসকিউএল-নির্দিষ্ট।
sh4

পাঠ্যের মধ্যে বন্ধনী অন্তর্ভুক্ত করার সময় আমি একটি সমস্যার মুখোমুখি হয়েছি, এটি কাজ করছে না। পছন্দ: "কোড (এলসি)"
ওশান উইসম্প্পারুমা

8

ব্যবহার ~*INSTR কার্যকারিতা সঙ্গে, কর্মক্ষমতার উপর ব্যাপকভাবে উন্নত করতে পারেন।

SELECT id FROM groups WHERE name ~* 'adm'

নামের সাথে সারিগুলি প্রত্যাবর্তন করে যা 'অ্যাডম' এর সমান হয়।


1
আরে, রবিন, এসওকে স্বাগতম! জেমস ব্রাউন এর উত্তর ইতিমধ্যে এই সমাধান প্রস্তাব করেছে। অতিরিক্তভাবে, আপনার প্রস্তাবিত উত্তর কোনওভাবেই রেজেক্সকে উপার্জন করতে পারে না।
রাফায়েল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.