php - এইচপ - মূল্য সংযোজন কর দিবস



পিএইচপি সহ MySQL জন্য ব্যবহার করার জন্য সবচেয়ে ভাল সংযোজন কি? (8)

আপনার ডাটাবেস আপলোড ফাইলটিতে, কোন লাইনের আগে ফলোইন লাইন যুক্ত করুন:

SET NAMES utf8;

এবং আপনার সমস্যা সমাধান করা উচিত।

মাইএসকিউএল-এ কোনও সাধারণ ওয়েবসাইটের জন্য কোনও "সর্বোত্তম" পছন্দ থাকলে আমি ভাবছি যে আপনি কোনও ওয়েবসাইটে প্রবেশ করতে চান তা নিশ্চিত করার 100% নিশ্চিত না? আমি বুঝতে পারি যে সমস্ত এনকোডিংগুলি একই রকম হওয়া উচিত, যেমন MySQL, Apache, HTML এবং পিএইচপি এর ভিতরে যেকোনো কিছু।

অতীতে আমি "ইউটিএফ -8" এ আউটপুট আউটপুট করতে পিএইচপি সেট করেছি, কিন্তু মাইএসকিউএল এ এই মিলনটি কোন মিলন করে? আমি মনে করি এটি ইউটিএফ -8 একের মধ্যে একটি, তবে আমি আগে utf8_unicode_ci , utf8_general_ci , এবং utf8_bin ব্যবহার utf8_unicode_ci


Answer #1

আমি এই সংযোজন চার্ট সহায়ক খুঁজে পাওয়া যায় নি। http://collation-charts.org/mysql60/ । আমি নিশ্চিত utf8_general_ci যদিও কোন নিশ্চিত না।

উদাহরণস্বরূপ এখানে utf8_swedish_ci এর জন্য চার্ট। এটি কোন অক্ষরটিকে একই হিসাবে ব্যাখ্যা করে তা দেখায়। http://collation-charts.org/mysql60/mysql604.utf8_swedish_ci.html


Answer #2

ইউটিএফ -8 পাঠ্য তথ্যের জন্য, আপনাকে utf8_general_ci ব্যবহার করতে হবে কারণ ...

  • utf8_bin : স্ট্রিং প্রতিটি চরিত্র বাইনারি মান দ্বারা স্ট্রিং তুলনা

  • utf8_general_ci : সাধারণ ভাষা নিয়ম ব্যবহার করে এবং কেস-অসংবেদক তুলনা ব্যবহার করে স্ট্রিংগুলির তুলনা করুন

উকিল এটি দ্রুত এবং আরো দক্ষ / আরো দরকারী তথ্য অনুসন্ধান এবং সূচী করা উচিত।


Answer #3

গুউস দ্বারা হাইলাইট করা ক্ষেত্রে, আমি utf8_bin (কঠোর মেলিং, ভুল ক্রম) এর পরিবর্তে utf8_unicode_cs (কেস সংবেদনশীল, কঠোর মেলিং, সর্বাধিক অংশে সঠিকভাবে অর্ডার করার) ব্যবহার করে সুপারিশ করব।

যদি ব্যবহারকারীর অনুসন্ধানের উদ্দেশ্যে ক্ষেত্রটি অনুসন্ধান করা হয় তবে ব্যবহারকারীর সাথে মিলিত হওয়ার পরে utf8_general_ci বা utf8_unicode_ci ব্যবহার করুন। উভয় ক্ষেত্রে অসংবেদী, এক অলসভাবে মিলবে ('ß' সমান 'গুলি, এবং না' ss)। এছাড়াও ভাষা নির্দিষ্ট সংস্করণ রয়েছে, যেমন utf8_german_ci যেখানে হারানো মেলাটি নির্দিষ্ট ভাষার জন্য আরও উপযুক্ত।

[সম্পাদনা - প্রায় 6 বছর পরে]

আমি আর MySQL এ "utf8" চরিত্র সেটটি সুপারিশ করি না এবং এর পরিবর্তে "utf8mb4" চরিত্র সেটটি সুপারিশ করি। তারা প্রায় পুরোপুরি মিলছে, তবে একটু বেশি (অনেক) ইউনিকোড অক্ষরগুলির জন্য মঞ্জুরি দেয়।

প্রকৃতপক্ষে, মাইএসকিউএলটি "ইউটিএফ 8" চরিত্র সেট এবং "ইউটিএফ 8" স্পেসিফিকেশনটির সাথে মিলিত হওয়ার জন্য সংশ্লিষ্ট সংযোজনকে আপডেট করতে হবে, তবে পরিবর্তে, একটি পৃথক চরিত্র সেট এবং সম্পর্কিত সংঘর্ষের ফলে ইতিমধ্যে তাদের অসম্পূর্ণ "utf8" অক্ষর সেট ব্যবহার করে স্টোরেজ ডিজিটেশন প্রভাবিত করবে না ।


Answer #4

প্রধান পার্থক্য সঠিকতা বাছাই করা হয় (ভাষা অক্ষর তুলনা) এবং কর্মক্ষমতা। একমাত্র বিশেষ একটি utf8_bin যা বাইনারি ফর্ম্যাটে অক্ষরগুলির তুলনা করার জন্য।

utf8_general_ci utf8_unicode_ci চেয়ে কিছুটা দ্রুত, কিন্তু কম সঠিক (সাজানোর জন্য)। নির্দিষ্ট ভাষা utf8 এনকোডিং (যেমন utf8_swedish_ci ) অতিরিক্ত ভাষা নিয়ম রয়েছে যা তাদেরকে সেই ভাষাগুলিতে সাজানোর জন্য সবচেয়ে সঠিক করে তোলে। বেশিরভাগ সময় আমি utf8_unicode_ci ব্যবহার utf8_unicode_ci (আমি ছোট পারফরম্যান্সের উন্নতির সঠিকতা পছন্দ করি), যদি না আমার নির্দিষ্ট ভাষা পছন্দ করার একটি ভাল কারণ থাকে।

আপনি MySQL ম্যানুয়ালের নির্দিষ্ট ইউনিকোড চরিত্র সেটগুলিতে আরো পড়তে পারেন - http://dev.mysql.com/doc/refman/5.0/en/charset-unicode-sets.html


Answer #5

মূলত, এটি একটি স্ট্রিং আপনি কিভাবে মনে করেন উপর নির্ভর করে।

গুগাস দ্বারা হাইলাইট করা সমস্যার কারণে আমি সবসময় utf8_bin ব্যবহার করি। আমার মতে, যতদূর ডাটাবেস সংশ্লিষ্ট হওয়া উচিত, একটি স্ট্রিং এখনও একটি স্ট্রিং। একটি স্ট্রিংটি UTF-8 অক্ষরগুলির একটি সংখ্যা। একটি চরিত্র একটি বাইনারি উপস্থাপনা আছে তাই কেন আপনি ব্যবহার করছেন ভাষা জানা প্রয়োজন? সাধারণত, লোকেরা বহুভাষিক সাইটগুলির সুযোগের সাথে সিস্টেমগুলির জন্য ডেটাবেসগুলি তৈরি করবে। এটি একটি চরিত্র সেট হিসাবে UTF-8 ব্যবহার করার পুরো পয়েন্ট। আমি একটি বিশুদ্ধবাদী একটি বিট কিন্তু আমি মনে করি বাগ ঝুঁকি ব্যাপকভাবে indexing পেতে পারে সামান্য সুবিধা ওজন অতিক্রম করে। কোন ভাষা সংক্রান্ত নিয়ম ডিবিএমএসের তুলনায় অনেক উচ্চ স্তরে করা উচিত।

আমার বইগুলিতে "মান" কখনো এক মিলিয়ন বছরে "Valúe" সমান হবে না।

আমি যদি একটি টেক্সট ক্ষেত্র সংরক্ষণ করতে এবং একটি কেস অসংবেদী অনুসন্ধান করতে চাই, আমি MySQL স্ট্রিং ফাংশনগুলি পিএইচপি ফাংশন যেমন LOWER () এবং php ফাংশন স্ট্রোলোলওয়ার () সহ ব্যবহার করব।


Answer #6

utf8_general_ci ব্যবহার করার সময় ঘটতে পারে এমন এই সমস্যা সম্পর্কে খুব সচেতন থাকুন।

utf8_general_ci সংযোজন ব্যবহার করা হলে, MySQL নির্বাচিত বিবৃতিতে কিছু অক্ষরের মধ্যে পার্থক্য করবে না। এটি খুব কদর্য বাগ হতে পারে - বিশেষ করে উদাহরণস্বরূপ, যেখানে ব্যবহারকারীর নাম জড়িত। ডাটাবেস সারণী ব্যবহার করে বাস্তবায়ন উপর নির্ভর করে, এই সমস্যা দূষিত ব্যবহারকারীদের প্রশাসক অ্যাকাউন্টের সাথে মিলে একটি ব্যবহারকারীর নাম তৈরি করতে অনুমতি দিতে পারে।

এই সমস্যাটি খুব কমই 5.x সংস্করণগুলিতে নিজেকে প্রকাশ করে - এই আচরণটি পরে পরিবর্তিত হলে আমি নিশ্চিত নই।

আমি কোন DBA নই, কিন্তু এই সমস্যা এড়ানোর জন্য, আমি সবসময় একটি কেস-অসংবেদক একটার পরিবর্তে utf8-bin দিয়ে যাই।

নীচের লিপি উদাহরণ দ্বারা সমস্যা বর্ণনা করে।

-- first, create a sandbox to play in
CREATE DATABASE `sandbox`;
use `sandbox`;

-- next, make sure that your client connection is of the same 
-- character/collate type as the one we're going to test next:
charset utf8 collate utf8_general_ci

-- now, create the table and fill it with values
CREATE TABLE `test` (`key` VARCHAR(16), `value` VARCHAR(16) )
    CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO `test` VALUES ('Key ONE', 'value'), ('Key TWO', 'valúe');

-- (verify)
SELECT * FROM `test`;

-- now, expose the problem/bug:
SELECT * FROM test WHERE `value` = 'value';

--
-- Note that we get BOTH keys here! MySQLs UTF8 collates that are 
-- case insensitive (ending with _ci) do not distinguish between 
-- both values!
--
-- collate 'utf8_bin' doesn't have this problem, as I'll show next:
--

-- first, reset the client connection charset/collate type
charset utf8 collate utf8_bin

-- next, convert the values that we've previously inserted in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET utf8 COLLATE utf8_bin;

-- now, re-check for the bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Note that we get just one key now, as you'd expect.
--
-- This problem appears to be specific to utf8. Next, I'll try to 
-- do the same with the 'latin1' charset:
--

-- first, reset the client connection charset/collate type
charset latin1 collate latin1_general_ci

-- next, convert the values that we've previously inserted
-- in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET latin1 COLLATE latin1_general_ci;

-- now, re-check for the bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Again, only one key is returned (expected). This shows 
-- that the problem with utf8/utf8_generic_ci isn't present 
-- in latin1/latin1_general_ci
--
-- To complete the example, I'll check with the binary collate
-- of latin1 as well:

-- first, reset the client connection charset/collate type
charset latin1 collate latin1_bin

-- next, convert the values that we've previously inserted in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET latin1 COLLATE latin1_bin;

-- now, re-check for the bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Again, only one key is returned (expected).
--
-- Finally, I'll re-introduce the problem in the exact same 
-- way (for any sceptics out there):

-- first, reset the client connection charset/collate type
charset utf8 collate utf8_generic_ci

-- next, convert the values that we've previously inserted in the table
ALTER TABLE `test` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;

-- now, re-check for the problem/bug
SELECT * FROM test WHERE `value` = 'value';

--
-- Two keys.
--

DROP DATABASE sandbox;

Answer #7

এটি utf8mb4 সাথে অক্ষর সেট utf8mb4 ব্যবহার করা ভাল।

চরিত্র সেট, utf8 , শুধুমাত্র অল্প সংখ্যক UTF-8 কোড পয়েন্ট সমর্থন করে, প্রায় 6% সম্ভাব্য অক্ষর। utf8 শুধুমাত্র বেসিক বহুভাষিক প্লেন (BMP) সমর্থন করে। সেখানে 16 অন্যান্য প্লেন। প্রতিটি সমতল 65,536 অক্ষর রয়েছে। utf8mb4 সব 17 প্লেন সমর্থন করে।

MySQL 4 বাইট UTF-8 অক্ষরগুলিকে দূষিত ডেটাতে পরিণত করবে।

utf8mb4 চরিত্র সেটটি utf8mb4 এ মাইএসকিউএল 5.5.3 এ উপস্থাপিত হয়েছিল।

নতুন চরিত্র সেট ব্যবহার করার জন্য প্রয়োজনীয় কিছু পরিবর্তন তুচ্ছ নয়:

  • পরিবর্তন আপনার অ্যাপ্লিকেশন ডাটাবেস অ্যাডাপ্টারের মধ্যে করা প্রয়োজন হতে পারে।
  • ক্যারেক্টার সেট, কল্যাণ এবং barracuda এ innodb_file_format স্যুইচিং সহ সেটিংস my.cnf এ পরিবর্তন করতে হবে।
  • এসকিউএল তৈরি বিবৃতি অন্তর্ভুক্ত করতে হতে পারে: ROW_FORMAT=DYNAMIC
    • VARCHAR (192) এবং বৃহত্তর সূচকের জন্য DYNAMIC প্রয়োজন।

দ্রষ্টব্য: Antelope থেকে Barracuda স্যুইচিং, একবার থেকে MySQL পরিষেবা পুনরায় আরম্ভ করার প্রয়োজন হতে পারে। innodb_file_format_max মাইএসকিউএল পরিষেবাটি পুনরায় চালু হওয়ার পরে পর্যন্ত পরিবর্তন হয় না: innodb_file_format = barracuda

MySQL পুরানো Antelope InnoDB ফাইল বিন্যাস ব্যবহার করে। Barracuda গতিশীল সারির ফরম্যাটগুলিকে সমর্থন করে, যা আপনি যদি utf8mb4 স্যুইচ করার পরে সূচী এবং কীগুলি তৈরির জন্য SQL ত্রুটিগুলি আঘাত করতে না চান তবে এটি প্রয়োজন হবে: utf8mb4

  • # 1709 - সূচক কলাম আকার খুব বড়। সর্বাধিক কলামের আকার 767 বাইট।
  • # 1071 - নির্দিষ্ট কী খুব দীর্ঘ ছিল; সর্বোচ্চ কী দৈর্ঘ্য 767 বাইট হয়

নিম্নলিখিত দৃশ্যকল্পটি MySQL 5.6.17 এ পরীক্ষা করা হয়েছে: ডিফল্টরূপে, MySQL এভাবে কনফিগার করা হয়েছে:

SHOW VARIABLES;

innodb_large_prefix = OFF
innodb_file_format = Antelope

আপনার মাইএসকিউএল সেবা বন্ধ করুন এবং আপনার বিদ্যমান my.cnf বিকল্প যোগ করুন:

[client]
default-character-set= utf8mb4

[mysqld]
explicit_defaults_for_timestamp = true
innodb_large_prefix = true
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_per_table = true

# Character collation
character_set_server=utf8mb4
collation_server=utf8mb4_unicode_ci

উদাহরণ এসকিউএল তৈরি বিবৃতি:

CREATE TABLE Contacts (
 id INT AUTO_INCREMENT NOT NULL,
 ownerId INT DEFAULT NULL,
 created timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
 modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
 contact VARCHAR(640) NOT NULL,
 prefix VARCHAR(128) NOT NULL,
 first VARCHAR(128) NOT NULL,
 middle VARCHAR(128) NOT NULL,
 last VARCHAR(128) NOT NULL,
 suffix VARCHAR(128) NOT NULL,
 notes MEDIUMTEXT NOT NULL,
 INDEX IDX_CA367725E05EFD25 (ownerId),
 INDEX created (created),
 INDEX modified_idx (modified),
 INDEX contact_idx (contact),
 PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ENGINE = InnoDB ROW_FORMAT=DYNAMIC;
  • CREATE বিবৃতি থেকে ROW_FORMAT=DYNAMIC সরানো হলে আপনি INDEX contact_idx (contact) জন্য উত্পন্ন ত্রুটি # 1709 দেখতে পারেন।

দ্রষ্টব্য: contact প্রথম 128 টি অক্ষর সীমাবদ্ধ করার জন্য সূচীটি পরিবর্তন করা ROW_FORMAT=DYNAMIC সাথে ব্যারাকু ROW_FORMAT=DYNAMIC ব্যবহার করার প্রয়োজনীয়তাকে বাদ দেয়

INDEX contact_idx (contact(128)),

এছাড়াও নোট করুন: যখন এটি ক্ষেত্রের আকার VARCHAR(128) , এটি 128 বাইট নয়। আপনি 128, 4 বাইট অক্ষর বা 128, 1 বাইট অক্ষর ব্যবহার করতে পারেন।

এই INSERT বিবৃতিতে অবশ্যই ২ টি বাইটের 'Poo' চরিত্র 2 সারিতে থাকা উচিত:

INSERT INTO `Contacts` (`id`, `ownerId`, `created`, `modified`, `contact`, `prefix`, `first`, `middle`, `last`, `suffix`, `notes`) VALUES
(1, NULL, '0000-00-00 00:00:00', '2014-08-25 03:00:36', '1234567890', '12345678901234567890', '1234567890123456789012345678901234567890', '1234567890123456789012345678901234567890', '12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678', '', ''),
(2, NULL, '0000-00-00 00:00:00', '2014-08-25 03:05:57', 'poo', '12345678901234567890', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', ''),
(3, NULL, '0000-00-00 00:00:00', '2014-08-25 03:05:57', 'poo', '12345678901234567890', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '123💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩💩', '', '');

আপনি last কলাম দ্বারা ব্যবহৃত স্থানটি দেখতে পারেন:

mysql> SELECT BIT_LENGTH(`last`), CHAR_LENGTH(`last`) FROM `Contacts`;
+--------------------+---------------------+
| BIT_LENGTH(`last`) | CHAR_LENGTH(`last`) |
+--------------------+---------------------+
|               1024 |                 128 | -- All characters are ASCII
|               4096 |                 128 | -- All characters are 4 bytes
|               4024 |                 128 | -- 3 characters are ASCII, 125 are 4 bytes
+--------------------+---------------------+

আপনার ডাটাবেস অ্যাডাপ্টারে, আপনি আপনার সংযোগের জন্য অক্ষর এবং সংযোজন সেট করতে চাইতে পারেন:

SET NAMES 'utf8mb4' COLLATE 'utf8mb4_unicode_ci'

পিএইচপি, এটি জন্য সেট করা হবে: \PDO::MYSQL_ATTR_INIT_COMMAND

তথ্যসূত্র:





collation