আমার একটি ফাংশন রয়েছে যা মিশ্র কেস সহ পাঁচটি অক্ষর প্রদান করে। যদি আমি এই স্ট্রিংয়ে কোনও জিজ্ঞাসা করি তা কেস নির্বিশেষে মানটি ফিরিয়ে দেবে।
আমি কীভাবে মাইএসকিউএল স্ট্রিং কোয়েরি কেসকে সংবেদনশীল করে তুলতে পারি?
আমার একটি ফাংশন রয়েছে যা মিশ্র কেস সহ পাঁচটি অক্ষর প্রদান করে। যদি আমি এই স্ট্রিংয়ে কোনও জিজ্ঞাসা করি তা কেস নির্বিশেষে মানটি ফিরিয়ে দেবে।
আমি কীভাবে মাইএসকিউএল স্ট্রিং কোয়েরি কেসকে সংবেদনশীল করে তুলতে পারি?
উত্তর:
http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html
ডিফল্ট অক্ষর সেট এবং কোলেশনটি হ'ল ল্যাটিন 1 এবং ল্যাটিন 1_সুইডিস_সি, সুতরাং ননবাইনারি স্ট্রিং তুলনাগুলি ডিফল্টরূপে সংবেদনশীল হয় না। এর অর্থ হ'ল আপনি যদি কল_নাম 'লাইক' একটি% 'দিয়ে অনুসন্ধান করেন তবে আপনি কলামের মানগুলি A বা a দিয়ে শুরু করবেন। এই অনুসন্ধান কেসটিকে সংবেদনশীল করতে, নিশ্চিত হয়ে নিন যে কোনও অপারেন্ডের কেস সংবেদনশীল বা বাইনারি কোলেশন রয়েছে। উদাহরণস্বরূপ, আপনি যদি একটি কলাম এবং একটি স্ট্রিংয়ের তুলনা করছেন যা উভয়টিতেই ল্যাটিন 1 বর্ণচিহ্ন সেট রয়েছে, আপনি কোল্যাট অপারেটরটি ল্যাটিন 1_জেনারাল_সিএস বা ল্যাটিন 1_বিন কোলেশন তৈরি করতে ব্যবহার করতে পারেন:
col_name COLLATE latin1_general_cs LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_general_cs
col_name COLLATE latin1_bin LIKE 'a%'
col_name LIKE 'a%' COLLATE latin1_bin
আপনি যদি চান যে কোনও কলামটি সর্বদা কেস-সংবেদনশীল ফ্যাশনে চিকিত্সা করা যায় তবে কেস সংবেদনশীল বা বাইনারি কোলেশন দিয়ে এটি ঘোষণা করুন।
SELECT 'email' COLLATE utf8_bin = 'Email'
সুসংবাদটি হ'ল যদি আপনার কেস-সংবেদনশীল কোয়েরি করা দরকার হয় তবে এটি করা খুব সহজ:
SELECT * FROM `table` WHERE BINARY `column` = 'value'
convert(char(0x65,0xcc,0x88) using utf8)
(অর্থাত e
সঙ্গে ¨
যোগ করা হয়েছে) এবং convert(char(0xc3,0xab) using utf8)
(অর্থাত ë
), কিন্তু যোগ BINARY
তাদের অসম করতে হবে।
ক্রেগ হোয়াইট পোস্ট করা উত্তর, বড় পারফরম্যান্স পেনাল্টি আছে
SELECT * FROM `table` WHERE BINARY `column` = 'value'
কারণ এটি সূচকগুলি ব্যবহার করে না। সুতরাং, হয় আপনাকে এখানে উল্লেখ করার মতো টেবিলের জোট পরিবর্তন করতে হবে https://dev.mysql.com/doc/refman/5.7/en/case- حساسیت . html ।
অথবা
সবচেয়ে সহজ ফিক্স, আপনার একটি মান বিনা ব্যবহার করা উচিত।
SELECT * FROM `table` WHERE `column` = BINARY 'value'
যেমন।
mysql> EXPLAIN SELECT * FROM temp1 WHERE BINARY col1 = "ABC" AND col2 = "DEF" ;
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | temp1 | ALL | NULL | NULL | NULL | NULL | 190543 | Using where |
+----+-------------+--------+------+---------------+------+---------+------+--------+-------------+
বনাম
mysql> EXPLAIN SELECT * FROM temp1 WHERE col1 = BINARY "ABC" AND col2 = "DEF" ;
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
| 1 | SIMPLE | temp1 | range | col1_2e9e898e | col1_2e9e898e | 93 | NULL | 2 | Using index condition; Using where |
+----+-------------+-------+-------+---------------+---------------+---------+------+------+------------------------------------+
enter code here
1 সারি সেট (0.00 সেকেন্ড)
= অপারেটর ব্যবহারের পরিবর্তে, আপনি লাইক বা বাইনারি পছন্দ করতে পারেন
// this returns 1 (true)
select 'A' like 'a'
// this returns 0 (false)
select 'A' like binary 'a'
select * from user where username like binary 'a'
এটি 'ক' নেবে এবং তার অবস্থা 'এ' নয়
বিনারি ব্যবহারের আগে একটি সূচক ব্যবহার করতে, আপনার কাছে যদি বড় টেবিল থাকে তবে আপনি এ জাতীয় কিছু করতে পারেন।
SELECT
*
FROM
(SELECT * FROM `table` WHERE `column` = 'value') as firstresult
WHERE
BINARY `column` = 'value'
সাবকিউরিটির ফলস্বরূপ একটি ছোট ছোট কেস-সংবেদনশীল উপসেট হবে যার পরে আপনি একমাত্র কেস-সংবেদনশীল ম্যাচটি নির্বাচন করেন।
জিজ্ঞাসিত হওয়া কলামটির জঙ্গি পরিবর্তন না করে কেস সংবেদনশীল স্ট্রিং তুলনা সম্পাদনের সর্বাধিক সঠিক উপায় হ'ল কলামটির সাথে যে মানটির তুলনা করা হচ্ছে তার জন্য একটি অক্ষর সেট এবং কোলেশন স্পষ্টভাবে নির্দিষ্ট করা।
select * from `table` where `column` = convert('value' using utf8mb4) collate utf8mb4_bin;
binary
করবেন না ?binary
অপারেটরটি ব্যবহার অপরিহার্য কারণ এটি এনকোডযুক্ত স্ট্রিংগুলির আসল বাইটের তুলনা করে। যদি আপনি আলাদা আলাদা অক্ষর ব্যবহার করে এনকোড করা দুটি স্ট্রিংয়ের আসল বাইটগুলি তুলনা করেন তবে দুটি স্ট্রিং সেট করে যা তারা সমান হতে পারে না। উদাহরণস্বরূপ, যদি আপনার কাছে একটি কলাম থাকে যা latin1
অক্ষর সেট ব্যবহার করে এবং আপনার সার্ভার / সেশন অক্ষর সেট থাকে utf8mb4
, তবে আপনি যখন কলামটি 'ক্যাফে' এর মতো একটি অ্যাকসেন্ট যুক্ত স্ট্রিংয়ের সাথে তুলনা করেন তখন এটি একই স্ট্রিংযুক্ত সারিগুলির সাথে মেলে না! এর কারণ এ latin1
দ্বীপ বাইট হিসাবে এনকোডেড হয়েছে 0xE9
কিন্তু utf8
এটিকে দুটি বাইট: 0xC3A9
।
convert
পাশাপাশি ব্যবহার কেন collate
?কোলেশনগুলি অবশ্যই অক্ষরের সাথে মেলে। সুতরাং যদি আপনার সার্ভার বা সেশনটি latin1
অক্ষর সেটটি ব্যবহার করতে সেট করা থাকে তবে আপনাকে অবশ্যই ব্যবহার করতে হবে collate latin1_bin
তবে যদি আপনার অক্ষর সেট থাকে তবে utf8mb4
আপনাকে অবশ্যই ব্যবহার করতে হবে collate utf8mb4_bin
। অতএব সর্বাধিক দৃ solution় সমাধান হ'ল সর্বদা মানটিকে সর্বাধিক নমনীয় চরিত্রের সেটে রূপান্তর করা এবং সেই অক্ষর সংকলনের জন্য বাইনারি কোলেশন ব্যবহার করা।
convert
এবং collate
মানটিতে এবং কলামটি নয় কেন প্রয়োগ করবেন ?তুলনা করার আগে আপনি যখন কোনও কলামে কোনও রূপান্তরকারী ফাংশন প্রয়োগ করেন এটি যখন কলামটির জন্য উপস্থিত থাকে তবে ক্যোয়ারী ইঞ্জিনটিকে একটি সূচক ব্যবহার থেকে বাধা দেয়, যা নাটকীয়ভাবে আপনার ক্যোয়ারিকে ধীর করে দিতে পারে। অতএব যেখানেই সম্ভব তার পরিবর্তে মানটি রূপান্তর করা সর্বদা ভাল। যখন দুটি স্ট্রিং মানগুলির মধ্যে একটি তুলনা করা হয় এবং এর মধ্যে একটিতে একটি নির্দিষ্টভাবে নির্দিষ্ট কোলিশ থাকে, কোয়েরি ইঞ্জিনটি কোন মানটিতে প্রয়োগ করা হয় তা নির্বিশেষে সুস্পষ্ট সংগ্রহটি ব্যবহার করবে।
এটি লক্ষণীয় গুরুত্বপূর্ণ যে মাইএসকিএল কেবলমাত্র একটি _ci
কোলেশন (যা সাধারণত ডিফল্ট) ব্যবহার করে কলামগুলির ক্ষেত্রে সংবেদনশীল নয় , তবে অ্যাকসেন্ট সংবেদনশীলও বটে। এর অর্থ 'é' = 'e'
। বাইনারি কোলেশন (বা binary
অপারেটর) ব্যবহার স্ট্রিং তুলনা অ্যাকসেন্ট সংবেদনশীল পাশাপাশি কেস সংবেদনশীল করে তুলবে।
utf8mb4
?utf8
মাইএসকিউএল মধ্যে অক্ষর সেট উপনাম জন্য utf8mb3
যা করা হয়েছে সাম্প্রতিক সংস্করণে অবচিত হয়েছে কারণ এটি 4 বাইট অক্ষর (যা মত 🐈 স্ট্রিং এনকোডিং জন্য গুরুত্বপূর্ণ) সমর্থন করে না। আপনি যদি মাইএসকিএল দিয়ে ইউটিএফ 8 অক্ষর এনকোডিং ব্যবহার করতে চান তবে আপনার চরসেটটি ব্যবহার করা উচিত utf8mb4
।
মাইএসকিউএল সংস্করণগুলির জন্য 5.5 এর সমান বা উচ্চতর নীচে রয়েছে।
/Etc/mysql/my.cnf এ যুক্ত করুন
[mysqld]
...
character-set-server=utf8
collation-server=utf8_bin
...
অন্যান্য চেষ্টা করা সমস্ত কলিঙ্কগুলি কেস-সংবেদনশীল বলে মনে হয়েছিল, কেবল "utf8_bin" কাজ করেছিল।
এর পরে মাইএসকিএল পুনরায় চালু করতে ভুলবেন না:
sudo service mysql restart
Http://dev.mysql.com/doc/refman/5.0/en/case- সেনসেটিভিটিভিটিএমএল অনুসারে একটি "ল্যাটিন 1_বিন" রয়েছে।
"Utf8_general_cs" মাইএসকিএল স্টার্টআপ দ্বারা গ্রহণ করা হয়নি। (আমি "_সিএস" "কেস-সংবেদনশীল" হিসাবে পড়েছি - ???)
আপনি এই জাতীয় সংবেদনশীল ক্ষেত্রে BINARY ব্যবহার করতে পারেন
select * from tb_app where BINARY android_package='com.Mtime';
দুর্ভাগ্যক্রমে এই বর্গক্ষেত্র সূচকটি ব্যবহার করতে পারে না, আপনি সেই সূচকের উপর নির্ভরশীল প্রশ্নের উপর একটি পারফরম্যান্সের আঘাতের শিকার হবেন
mysql> explain select * from tb_app where BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
| 1 | SIMPLE | tb_app | NULL | ALL | NULL | NULL | NULL | NULL | 1590351 | 100.00 | Using where |
+----+-------------+--------+------------+------+---------------+------+---------+------+---------+----------+-------------+
ভাগ্যক্রমে, আমার এই সমস্যাটি সমাধান করার জন্য কয়েকটি কৌশল আছে
mysql> explain select * from tb_app where android_package='com.Mtime' and BINARY android_package='com.Mtime';
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
| 1 | SIMPLE | tb_app | NULL | ref | idx_android_pkg | idx_android_pkg | 771 | const | 1 | 100.00 | Using index condition |
+----+-------------+--------+------------+------+---------------------------+---------------------------+---------+-------+------+----------+-----------------------+
অসাধারণ!
আমি পাসওয়ার্ডগুলির সাথে তুলনা করে এমন একটি ফাংশন থেকে কোডটি আপনার সাথে ভাগ করে দিচ্ছি:
SET pSignal =
(SELECT DECODE(r.usignal,'YOURSTRINGKEY') FROM rsw_uds r WHERE r.uname =
in_usdname AND r.uvige = 1);
SET pSuccess =(SELECT in_usdsignal LIKE BINARY pSignal);
IF pSuccess = 1 THEN
/*Your code if match*/
ELSE
/*Your code if don't match*/
END IF;
declare pSuccess BINARY;
শুরুতে যুক্ত করা দরকার
ডিবি স্তরে কোনও পরিবর্তন করার দরকার নেই, এটি আপনাকে কার্যকর করবে এসকিউএল কোয়েরিতে পরিবর্তন করতে হবে।
উদাহরণ -
"SELECT * FROM <TABLE> where userId = '" + iv_userId + "' AND password = BINARY '" + iv_password + "'";
বাইনারি কীওয়ার্ড কেসকে সংবেদনশীল করে তুলবে।