mysql - # 1071-নির্দিষ্ট কী খুব দীর্ঘ ছিল; সর্বোচ্চ কী দৈর্ঘ্য 767 বাইট হয়




byte varchar (20)

যখন আমি নিম্নলিখিত কমান্ডটি চালিত করি:

ALTER TABLE `mytable` ADD UNIQUE (
`column1` ,
`column2`
);

আমি এই ত্রুটি বার্তা পেয়েছিলাম:

#1071 - Specified key was too long; max key length is 767 bytes

কলাম 1 এবং কলাম 2 সম্পর্কে তথ্য:

column1 varchar(20) utf8_general_ci
column2  varchar(500) utf8_general_ci

আমার মনে হয় varchar(20) শুধুমাত্র ২1 বাইটের প্রয়োজন এবং varchar(500) শুধুমাত্র 501 বাইটের প্রয়োজন। সুতরাং মোট বাইট 522, 767 এর চেয়ে কম। তাই আমি ত্রুটির বার্তা কেন পেয়েছি?

#1071 - Specified key was too long; max key length is 767 bytes

আমার মনে হয় ভার্চার (২0) শুধুমাত্র ২1 বাইটের প্রয়োজন এবং ওয়ারার (500) শুধুমাত্র 501 বাইটের প্রয়োজন। সুতরাং মোট বাইট 522, 767 এর চেয়ে কম। তাই আমি ত্রুটির বার্তা কেন পেয়েছি?

UTF8 এর জন্য স্ট্রিং সংরক্ষণ করতে প্রতি অক্ষর 3 বাইটের প্রয়োজন হয় , তাই আপনার ক্ষেত্রে 20+ 500 অক্ষর = 20 * 3 + 500 * 3 = 1560 বাইট যা 767 বাইটের অনুমতি ছাড়াই বেশি

UTF8 এর জন্য সীমা 767/3 = 255 অক্ষর , UTF8mb4 এর জন্য যা প্রতি চরিত্র 4 বাইট ব্যবহার করে তা 767/4 = 191 অক্ষর।

যদি আপনি সীমাটির চেয়ে বেশি কলাম ব্যবহার করতে চান তবে এই সমস্যার দুটি সমাধান রয়েছে:

  1. "সস্তা" এনকোডিং ব্যবহার করুন (যে প্রতি চরিত্র প্রতি কম বাইট প্রয়োজন)
    আমার ক্ষেত্রে, আমি এসইও স্ট্রিংয়ের জন্য শুধুমাত্র [A-z0-9\-] অক্ষরগুলি ব্যবহার করে নিবন্ধটির এসইও স্ট্রিং সহ কলামে অনন্য সূচক যুক্ত করতে চাই, আমি [A-z0-9\-] ব্যবহার করি যা প্রতি অক্ষর শুধুমাত্র একটি বাইট ব্যবহার করে এবং তাই কলাম থাকতে পারে 767 বাইট দৈর্ঘ্য।
  2. আপনার কলাম থেকে হ্যাশ তৈরি করুন এবং শুধুমাত্র এতে অনন্য সূচী ব্যবহার করুন
    আমার জন্য অন্য বিকল্প ছিল এসইও এর হ্যাশ সংরক্ষণের অন্য কলাম তৈরি করা, এই কলামটিতে অনন্য মান নিশ্চিত করা হবে এসইও মানগুলি অনন্য। আমি সন্ধান আপ দ্রুত মূল এসইও কলামে মূল সূচক যোগ হবে।

5 কার্যকারিতা:

সীমা 5.7.7 (মারিয়াডিবি 10.2.2?) মধ্যে উত্থাপিত হয়েছিল। এবং এটি 5.6 (10.1) কিছু কাজের সাথে বৃদ্ধি করা যেতে পারে।

আপনি যদি অক্ষর সেট utf8mb4 ব্যবহার করার চেষ্টা করার কারণে সীমাটি আঘাত করে থাকেন। তারপরে ত্রুটিটি এড়ানোর জন্য নিচেরগুলির মধ্যে একটি করুন (প্রতিটিটিতে একটি ত্রুটি রয়েছে):

  Upgrade to 5.7.7 for 3072 byte limit -- your cloud may not provide this;
  Change 255 to 191 on the VARCHAR -- you lose any values longer than 191 characters (unlikely?);
  ALTER .. CONVERT TO utf8 -- you lose Emoji and some of Chinese;
  Use a "prefix" index -- you lose some of the performance benefits.
  Or... Stay with older version but perform 4 steps to raise the limit to 3072 bytes:

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=1;
SET GLOBAL innodb_large_prefix=1;
logout & login (to get the global values);
ALTER TABLE tbl ROW_FORMAT=DYNAMIC;  -- (or COMPRESSED)

- http://mysql.rjweb.org/doc.php/limits#767_limit_in_innodb_indexes


Laravel জন্য 5.7 বা 5.6

অনুসরণ করার পদক্ষেপ

  1. App\Providers\AppServiceProvider.php যান।
  2. সরবরাহকারীর কাছে এটি যোগ করুন use Illuminate\Support\Facades\Schema; শীর্ষে।
  3. বুট ফাংশনের ভিতরে এই Schema::defaultStringLength(191);

যে সব, উপভোগ করুন।


MySQL স্ট্রিং প্রতি অক্ষর বাইট সংখ্যা জন্য সবচেয়ে খারাপ ক্ষেত্রে অনুমান। মাইএসকিউএল 'utf8' এনকোডিংয়ের জন্য, এটি প্রতি অক্ষর 3 বাইটের পরে যে এনকোডিং U+FFFF বাইরে অক্ষরগুলিকে অনুমতি দেয় না। MySQL 'utf8mb4' এনকোডিংয়ের জন্য, এটি প্রতি অক্ষর 4 বাইট, যেহেতু MySQL প্রকৃত UTF-8 কল করে।

সুতরাং আপনি অনুমান করছেন যে আপনি 'utf8' ব্যবহার করছেন, আপনার প্রথম কলামটি 60 বিট সূচকের এবং আপনার দ্বিতীয় 1500 টি গ্রহণ করবে।


অভিযোগ সূচী ক্ষেত্রের CHARSET পরিবর্তন করুন "latin1"
অর্থাৎ এলটার টেবিল টিবিএল পরিবর্তন মাইফিল্ড মাইফিল্ড ওয়ারচার (600) অক্ষর সেট latin1 ডিফল্ট নুল;
latin1 চার পরিবর্তে এক চরিত্রের জন্য এক বাইট লাগে


আপনার প্রশ্নের আগে এই প্রশ্নের চালান:

SET @@global.innodb_large_prefix = 1;

এই 3072 bytes সীমা বৃদ্ধি হবে।


আপনি ত্রুটির বার্তা কেন পেয়েছেন তার উত্তরটি ইতিমধ্যে এখানে অনেক ব্যবহারকারীর দ্বারা উত্তর দেওয়া হয়েছে। আমার উত্তর কিভাবে এটি ঠিক করা এবং এটি ব্যবহার করা হয়।

এই লিঙ্ক থেকে পড়ুন।

  1. মাইএসকিউএল ক্লায়েন্ট খুলুন (অথবা মারিয়াডিবি ক্লায়েন্ট)। এটি একটি কমান্ড লাইন টুল।
  2. এটি আপনার পাসওয়ার্ড জিজ্ঞাসা করবে, আপনার সঠিক পাসওয়ার্ড লিখুন।
  3. এই কমান্ড use my_database_name; করে আপনার ডাটাবেস নির্বাচন করুন use my_database_name;

ডাটাবেস পরিবর্তিত

  1. set global innodb_large_prefix=on;

কোয়েরি ঠিক আছে, 0 সারি প্রভাবিত হয়েছে (0.00 সেকেন্ড)

  1. set global innodb_file_format=Barracuda;

প্রশ্ন ঠিক আছে, 0 সারি প্রভাবিত হয়েছে (0.02 সেকেন্ড)

  1. PhpMyAdmin বা সহজ ব্যবস্থাপনা জন্য যে মত কিছু আপনার ডাটাবেস যান। > ডাটাবেস নির্বাচন করুন> টেবিল গঠন দেখুন> ক্রিয়াকলাপ ট্যাবে যান। > ROW_FORMAT থেকে DYNAMIC পরিবর্তন করুন এবং পরিবর্তনগুলি সংরক্ষণ করুন।
  2. টেবিলের গঠন ট্যাবে যান> অনন্য বোতামে ক্লিক করুন।
  3. সম্পন্ন. এখন এটা কোন ত্রুটি থাকা উচিত।

এই ঠিকানার সমস্যা হল যদি আপনি অন্য সার্ভারে ডিবি রপ্তানি করেন (উদাহরণস্বরূপ স্থানীয় হোস্ট থেকে বাস্তব হোস্ট) এবং আপনি সেই সার্ভারে MySQL কমান্ড লাইনটি ব্যবহার করতে পারবেন না। আপনি এটি কাজ করতে পারবেন না।


আপনি দীর্ঘ কলামের MD5 একটি কলাম যোগ করতে পারে


আপনি সীমা আঘাত যখন। নিম্নলিখিত সেট করুন।

  • INNODB utf8 VARCHAR(255)
  • INNODB utf8mb4 VARCHAR(191)

আমার ক্ষেত্রে, আমি এই সমস্যাটি ছিল যখন আমি লিনাক্স পুনঃনির্দেশনার আউটপুট / ইনপুট অক্ষরগুলি ব্যবহার করে ডেটাবেস ব্যাক আপ করছিলাম। অতএব, আমি নিচে বর্ণনা হিসাবে সিনট্যাক্স পরিবর্তন। PS: একটি linux বা mac টার্মিনাল ব্যবহার করে।

ব্যাকআপ (> পুনঃনির্দেশিত ছাড়া)

# mysqldump -u root -p databasename -r bkp.sql

পুনরুদ্ধার (<পুনঃনির্দেশ ছাড়া)

# mysql -u root -p --default-character-set=utf8 databasename
mysql> SET names 'utf8'
mysql> SOURCE bkp.sql

ত্রুটি "নির্দিষ্ট কী খুব দীর্ঘ ছিল; সর্বাধিক কী দৈর্ঘ্য 767 বাইট হয়" সহজ অদৃশ্য।


আমি এই সমস্যা সংশোধন করেছিলাম:

varchar(200) 

সঙ্গে প্রতিস্থাপিত

varchar(191)

200 টিরও বেশি সংখ্যক ওয়ারচার তাদের 191 দিয়ে প্রতিস্থাপন করে বা পাঠ্য সেট করে।


উপসর্গ সীমাবদ্ধতার কারণে এই ত্রুটি ঘটবে। 767 বাইট 5.7 এর আগে MySQL সংস্করণগুলিতে InnoDB সারণির জন্য উল্লিখিত পূর্বরূপ সীমাবদ্ধতা। এটি MySAM টেবিল জন্য 1,000 বাইট দীর্ঘ। মাইএসকিউএল সংস্করণ 5.7 এবং ঊর্ধ্বমুখী এই সীমা 3072 বাইট বৃদ্ধি করা হয়েছে।

পরিষেবাটিতে নিম্নলিখিতগুলি চালানো আপনাকে ত্রুটি প্রদান করে আপনার সমস্যার সমাধান করা উচিত। এই মাইএসকিউএল সিএলআই চালানো হবে।

SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=on;
SET GLOBAL innodb_large_prefix=on;

এখানে আমার মূল উত্তর:

আমি শুধু ডাটাবেস ড্রপ এবং এই মত recreate, এবং ত্রুটি চলে গেছে:

drop database if exists rhodes; create database rhodes default CHARACTER set utf8 default COLLATE utf8_general_ci;

যাইহোক, এটা সব ক্ষেত্রে জন্য কাজ করে না।

এটি আসলে VARCHAR কলামগুলিতে সূচীগুলি ব্যবহার করার একটি সমস্যা, যা অক্ষর সেট utf8 (বা utf8mb4 ) সহ, VARCHAR কলামগুলির সাথে যা নির্দিষ্ট সংখ্যক অক্ষরের বেশি থাকে। utf8mb4 ক্ষেত্রে, নির্দিষ্ট দৈর্ঘ্য 191।

মাইএসকিউএল ডাটাবেসে দীর্ঘ সূচীগুলি কীভাবে ব্যবহার করবেন তা আরও তথ্যের জন্য অনুগ্রহ করে এই নিবন্ধে লং ইনডেক্স বিভাগটি পড়ুন: http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database-character-set-to-utf8mb4


কি চরিত্র এনকোডিং আপনি ব্যবহার করছেন? কিছু চরিত্র সেট (যেমন UTF-16, et cetera) প্রতি অক্ষর এক বাইট বেশি ব্যবহার করে।


নিচের কলামের উপর ভিত্তি করে, ২ টি পরিবর্তনশীল স্ট্রিং কলাম utf8_general_ci সংযোজন ব্যবহার করে ( utf8 অক্ষরটি উল্লিখিত হয়)।

মাইএসকিউএল ইন, utf8 চার্চেট প্রতিটি চরিত্রের জন্য সর্বাধিক 3 বাইট ব্যবহার করে। সুতরাং, এটি 500 * 3 = 1500 বাইট বরাদ্দ করতে হবে, যা 767 বাইট মাইএসকিউএল এর চেয়ে অনেক বেশি। এই কারণে আপনি এই 1071 ত্রুটি পেয়েছেন।

অন্য কথায়, আপনার চার্জারটির বাইট প্রতিনিধিত্বের উপর ভিত্তি করে চরিত্র গণনা গণনা করা প্রয়োজন কারণ প্রতিটি চার্চটি একক বাইট উপস্থাপনা (যেমন আপনি অনুমিত।) মাইএসকিউএলে IE utf8 সর্বাধিক 3-বাইট প্রতি চরিত্র, 767 / 3≈ ব্যবহার করে 255 অক্ষর, এবং utf8mb4 জন্য, সর্বাধিক 4-বাইট উপস্থাপনা, 767 / 4≈191 অক্ষর।

এটা যে MySQL এছাড়াও পরিচিত

column1 varchar(20) utf8_general_ci
column2  varchar(500) utf8_general_ci

যদি কোনও ভানচর VARCHAR(256) ক্ষেত্রের মধ্যে একটি UNIQUE ইনডেক্স স্থাপন করার জন্য INNODB / Utf-8 এর সাথে সমস্যা হয়, তবে এটি VARCHAR(255) । মনে হচ্ছে 255 সীমাবদ্ধতা।


Laravel ফ্রেমওয়ার্ক জন্য সমাধান

Laravel অনুযায়ী 5.4। * ডকুমেন্টেশন ; নিম্নরূপ app/Providers/AppServiceProvider.php ফাইলের boot পদ্ধতির অভ্যন্তরে আপনি ডিফল্ট স্ট্রিং দৈর্ঘ্য সেট করতে হবে:

use Illuminate\Support\Facades\Schema;

public function boot() 
{
    Schema::defaultStringLength(191); 
}

Laravel 5.4 দ্বারা দেওয়া এই ফিক্স ব্যাখ্যা । * ডকুমেন্টেশন :

Laravel ডিফল্টরূপে utf8mb4 চরিত্র সেট ব্যবহার করে, যা ডাটাবেসের মধ্যে "ইমোজিস" সংরক্ষণের জন্য সমর্থন অন্তর্ভুক্ত করে। আপনি যদি 5.7.7 রিলিজ বা 10.2.2 রিলিজের চেয়ে মারিয়াডিবি পুরানো এর চেয়ে পুরনো MySQL সংস্করণটি চালাচ্ছেন তবে মাইএসকিউএল তাদের জন্য সূচী তৈরি করার জন্য মাইগ্রেশনগুলির দ্বারা তৈরি ডিফল্ট স্ট্রিং দৈর্ঘ্য ম্যানুয়ালিভাবে কনফিগার করতে হবে। আপনি আপনার AppServiceProvider মধ্যে Schema::defaultStringLength পদ্ধতি কল করে এটি কনফিগার করতে পারেন।

বিকল্পভাবে, আপনি আপনার ডাটাবেসের জন্য innodb_large_prefix বিকল্প সক্ষম করতে পারেন। এই বিকল্পটি সঠিকভাবে কীভাবে সক্ষম করবেন তার নির্দেশাবলীর জন্য আপনার ডাটাবেসের ডকুমেন্টেশন পড়ুন।


আমি এই বিষয়ে কিছু অনুসন্ধান অবশেষে কিছু কাস্টম পরিবর্তন পেয়েছিলাম

মাইএসকিউএল ওয়ার্কবিনক এর জন্য 6.3.7 সংস্করণ গ্রাফিক্যাল ইন্টার ফেজ পাওয়া যায়

  1. Workbench শুরু করুন এবং সংযোগ নির্বাচন করুন।
  2. ব্যবস্থাপনা বা ইনস্ট্যান্স যান এবং বিকল্প ফাইল নির্বাচন করুন।
  3. Workbench আপনাকে কনফিগারেশন ফাইল পড়ার অনুমতি দেয় এবং তারপরে ওকে দুই বার চাপিয়ে দিয়ে অনুমতি দিন।
  4. কেন্দ্রস্থলে অ্যাডমিনিস্ট্রেটর অপশন ফাইল উইন্ডো আসে।
  5. InnoDB ট্যাবে যান এবং innodb_large_prefix টি চেক করুন যদি এটি সাধারণ বিভাগে চেক না করে।
  6. innodb_default_row_format বিকল্প মান সেট DYNAMIC।

6.3.7 সরাসরি বিকল্পগুলির জন্য সংস্করণগুলির জন্য উপলব্ধ নেই তাই কমান্ড প্রম্পটের সাথে যেতে হবে

  1. প্রশাসক হিসাবে সিএমডি শুরু করুন।
  2. মাইএসকিউএল সার্ভার ইনস্টল করা হয় যেখানে পরিচালক যান যান বেশিরভাগ ক্ষেত্রে এটি "সি: \ প্রোগ্রাম ফাইলগুলি \ MySQL \ MySQL সার্ভার 5.7 \ bin" হয় তাই কমান্ড "সিডি \" "সিডি প্রোগ্রাম ফাইলগুলি \ MySQL \ MySQL সার্ভার 5.7 \ bin" হয়।
  3. এখন রান কমান্ড mysql -u ব্যবহারকারী নাম-প ডাটাবেসেসিমা এখন এটি সংশ্লিষ্ট ব্যবহারকারীর পাসওয়ার্ড জানতে চাওয়া হয়েছে। পাসওয়ার্ড সরবরাহ করুন এবং MySQL প্রম্পটে প্রবেশ করুন।
  4. আমাদের কিছু গ্লোবাল সেটিংস সেট করতে হবে নীচের কমান্ডগুলি এক সেট এক গ্লোবাল innodb_large_prefix = on; বিশ্বব্যাপী innodb_file_format = বারাকুডা সেট করুন; বিশ্বব্যাপী innodb_file_per_table = সত্য সেট করুন;
  5. এখন শেষ পর্যন্ত আমাদের অবশ্যই প্রয়োজনীয় টেবিলের ROW_FORMAT পরিবর্তন করতে হবে তার COMPACT, এটি আমাদের DYAMAMIC এ সেট করতে হবে।
  6. নিম্নলিখিত কমান্ড পরিবর্তন টেবিল table_name ROW_FORMAT = DYNAMIC ব্যবহার করুন;
  7. সম্পন্ন

আমার জন্য, "# 1071 - নির্দিষ্ট কীটি অনেক লম্বা ছিল" এর সংখ্যাটি সর্বাধিক লম্বা ছিল 767 বাইট "কলামের আকার সীমিত করে প্রাথমিককি / অনিকিক সংযোজন পরিবর্তন করার পরে সমাধান করা হয়েছে।

ALTER TABLE `mytable` ADD UNIQUE (
`column1` (200) ,
`column2` (200)
);

আপনি যদি innodb_log_file_sizeসম্প্রতি পরিবর্তিত হয়ে থাকেন তবে পূর্ববর্তী মানটি পুনরুদ্ধার করার চেষ্টা করুন।





mysql-error-1071