दिलचस्प पोस्ट
Mysql डेटाबेस से मेरी BLOB छवि दिखाने के लिए मुझे अपने PHP पृष्ठ की आवश्यकता है C ++ / CLI आवरण के लिए मूल सी ++ के संदर्भ में उपयोग करने के लिए C # UIScrollView autolayout बाधाओं का उपयोग नहीं करता है कैसे जावा सरणी तर्क घोषणा वाक्यविन्यास "…" काम करता है? किसी व्यक्ति ने प्रकाशित शाखा को रीबेस या रीसेट करने के बाद मैं कैसे ठीक / पुन: सिंक्रनाइज़ कर सकता हूं? JOIN और इनर जॉइन के बीच का अंतर कोड प्रथम – क्या डाटा एनोटेशन या फ़्लुएंट एपीआई बेहतर है? मैं कैसे परीक्षण कर सकता हूँ यदि एक चर एक संख्या में है Bash? पूरी तरह से और वर्बोज जी ++ चेतावनियां सक्षम करने के लिए झंडे कस्टम डिस्क कैश के साथ पिकासो का उपयोग करना क्या कोई विवरण है कि कैसे __cmp__ पायथन 2 में डिक् ऑब्जेक्ट्स के लिए काम करता है? डुप्लिकेट को रोकने के लिए एक इतिहास रखने के लिए, सीमा के भीतर अनन्य संख्या उत्पन्न करें (0 – X) फ़ायरफ़ॉक्स में href = "फाइल: ///// …" के लिए वैकल्पिक हल सिंगलटन: इसे कैसे इस्तेमाल किया जाना चाहिए JQuery के साथ कुकीज़ बनाएं, पढ़ें और मिटाएं

# 1071 – निर्दिष्ट कुंजी बहुत लंबी थी; अधिकतम कुंजी लंबाई 767 बाइट्स है

जब मैंने निम्नलिखित कमांड निष्पादित की:

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) केवल 21 बाइट्स की आवश्यकता होती है, जबकि varchar(500) केवल 501 बाइट्स की आवश्यकता होती है तो कुल बाइट 522, 767 से कम है। तो मुझे त्रुटि संदेश क्यों मिला?

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

वेब के समाधान से एकत्रित समाधान "# 1071 – निर्दिष्ट कुंजी बहुत लंबी थी; अधिकतम कुंजी लंबाई 767 बाइट्स है"

767 बाइट्स MySQL संस्करण 5.6 (और पूर्व संस्करण) में InnoDB तालिकाओं के लिए कहा उपसर्ग सीमा है । MyISAM तालिकाओं के लिए 1,000 बाइट्स लंबा है MySQL 5.7 संस्करण में और ऊपर की सीमा को बढ़ाकर 3072 बाइट्स कर दिया गया है।

आपको यह भी जागरूक होना चाहिए कि यदि आप एक बड़े चार या वार्कर क्षेत्र पर इंडेक्स सेट करते हैं जो utf8mb4 एन्कोडेड है, तो आपको अधिकतम इंडेक्स प्रीफ़िक्स लम्बाई 767 बाइट्स (या 3072 बाइट्स) को 4 से 1 9 1 में विभाजित करना होगा। इसका कारण यह है एक utf8mb4 वर्ण की अधिकतम लंबाई चार बाइट्स है। एक utf8 वर्ण के लिए यह तीन बाइट होगा जिसके परिणामस्वरूप अधिकतम इंडेक्स उपसर्ग लंबाई 254 होगा।

आपके पास एक विकल्प है कि आप अपने VARCHAR क्षेत्रों पर निचली सीमा तक रहें।

एक अन्य विकल्प ( इस मुद्दे की प्रतिक्रिया के अनुसार) पूरी राशि के बजाय स्तंभ के उपसंशय प्राप्त करना है, अर्थात:

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

आप को लागू करने की कुंजी मिलनी चाहिए, लेकिन मुझे आश्चर्य है कि क्या यह इस इकाई के बारे में अपने डेटा मॉडल की समीक्षा करने के लिए होगा, यह देखने के लिए कि क्या सुधार है जो आपको माइस् SQL सीमा को मारने के बिना इच्छित व्यावसायिक नियमों को लागू करने की अनुमति देगा।

यदि किसी व्यक्ति को INNODB / Utf-8 के साथ कोई समस्या है जो किसी VARCHAR(256) फ़ील्ड पर एक UNIQUE अनुक्रमणिका डालते हैं, तो इसे VARCHAR(255) स्विच करें। ऐसा लगता है कि 255 सीमा है

जब आप सीमा को मारा निम्न सेट करें

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

MySQL स्ट्रिंग में प्रति चरित्र बाइट्स की संख्या के लिए सबसे खराब स्थिति मानता है। MySQL 'utf8' एन्कोडिंग के लिए, यह प्रति चरित्र 3 बाइट है क्योंकि उस एन्कोडिंग ने U+FFFF परे वर्णों को अनुमति नहीं दी है। MySQL 'utf8mb4' एन्कोडिंग के लिए, यह 4 बाइट्स प्रति चरित्र है, चूंकि MySQL वास्तविक UTF-8 को कॉल करता है।

मान लें कि आप 'utf8' का उपयोग कर रहे हैं, आपका पहला कॉलम सूचकांक के 60 बाइट्स लेगा, और आपका दूसरा दूसरा 1500

क्या वर्ण एन्कोडिंग आप प्रयोग कर रहे हैं? कुछ चरित्र सेट (जैसे यूटीएफ -16, एट वगैरह) प्रति चरित्र एक से अधिक बाइट का उपयोग करते हैं।

अपनी क्वेरी से पहले यह क्वेरी चलाएं:

 SET @@global.innodb_large_prefix = 1; 

इससे सीमा बढ़ाकर 3072 bytes

 Specified key was too long; max key length is 767 bytes 

आपको वह संदेश मिला क्योंकि 1 बाइट एक चरित्र के बराबर है, अगर आप latin-1 वर्ण सेट का उपयोग करते हैं। यदि आप utf8 उपयोग करते हैं, तो प्रत्येक चरित्र को आपकी बाइट कॉलम परिभाषित करते समय 3 बाइट्स माना जाएगा। यदि आप utf8mb4 उपयोग utf8mb4 , तो प्रत्येक कुंजी को आपके कुंजी कॉलम को परिभाषित करते समय 4 बाइट माना जाएगा। इस प्रकार, कुंजी क्षेत्र की अनुमति देने के लिए बाइट्स की संख्या निर्धारित करने के लिए, आपको 1, 3, या 4 (मेरी उदाहरण में), अपनी प्रमुख फ़ील्ड की वर्ण सीमा को गुणा करना होगा। यदि आप यूएफटी 8 एमबी 4 का उपयोग कर रहे हैं, तो आप केवल देशी, InnoDB, प्राथमिक कुंजी फ़ील्ड के लिए 1 9 1 वर्णों को परिभाषित कर सकते हैं। बस 767 बाइट्स का उल्लंघन नहीं करते।

आप लंबे कॉलम के एमडी 5 के एक कॉलम को जोड़ सकते हैं

मुझे लगता है कि varchar (20) केवल 21 बाइट्स की आवश्यकता होती है, जबकि varchar (500) को केवल 501 बाइट्स की आवश्यकता होती है तो कुल बाइट 522, 767 से कम है। तो मुझे त्रुटि संदेश क्यों मिला?

यूटीएफ 8 की स्ट्रिंग को स्टोर करने के लिए प्रति चरित्र 3 बाइट्स की आवश्यकता होती है , इसलिए आपके मामले में 20 + 500 वर्ण = 20 * 3 + 500 * 3 = 1560 बाइट्स जो 767 बाइट्स की अनुमति से अधिक है

यूटीएफ 8 की सीमा 767/3 = 255 अक्षरों के लिए है , जो यूटीएफ 8 एमबी 4 के लिए है, जो प्रति चरित्र 4 बाइट्स का उपयोग करता है यह 767/4 = 1 9 1 वर्ण है।


इस समस्या के दो समाधान हैं यदि आपको सीमा से अधिक स्तंभ का उपयोग करने की आवश्यकता है:

  1. "सस्ता" एन्कोडिंग का उपयोग करें (जो कि प्रत्येक चरित्र में कम बाइट्स की आवश्यकता होती है)
    मेरे मामले में, मुझे लेख के एसईओ स्ट्रिंग वाले अनोखा इंडेक्स को जोड़ने की जरूरत थी, क्योंकि मैं एसईओ के लिए केवल [A-z0-9\-] वर्णों का उपयोग करता हूं, मैं latin1_general_ci का उपयोग करता latin1_general_ci जो केवल एक बाइट प्रति चरित्र का उपयोग करता है और इसलिए कॉलम में हो सकता है 767 बाइट्स लंबाई
  2. अपने कॉलम से हैश बनाएं और उस पर अद्वितीय अनुक्रमणिका का उपयोग करें
    मेरे लिए दूसरा विकल्प था एक और स्तंभ बनाने के लिए जो एसईओ के हैश को स्टोर करेगा, इस कॉलम में UNIQUE कुंजी है ताकि यह सुनिश्चित हो सके कि एसईओ मूल्य अनूठे हैं। मैं मूल एसईओ कॉलम के लिए KEY सूचकांक को देखने में तेजी लाने के लिए भी KEY

यूटीएफएएमएमबी 4 का प्रयोग करते हुए एक VARCHAR (255) फ़ील्ड में एक अद्वितीय सूचकांक जोड़ने का प्रयास करते समय हमने इस मुद्दे का सामना किया। हालांकि समस्या पहले से ही अच्छी तरह से रेखांकित की गई है, मैं कुछ व्यावहारिक सलाह जोड़ना चाहता था कि हम इसे कैसे समझ गए और इसे सुलझा लिया।

Utf8mb4 का उपयोग करते समय, वर्ण 4 बाइट्स के रूप में गिनाते हैं, जबकि utf8 के तहत, वे 3 बाइट्स के रूप में कर सकते हैं। InnoDB डेटाबेस की एक सीमा होती है जिसमें अनुक्रमित केवल 767 बाइट्स हो सकते हैं। इसलिए यूटीएफ 8 का प्रयोग करते समय, आप 255 अक्षर (767/3 = 255) को स्टोर कर सकते हैं, लेकिन यूटीएफ 8 एमबी 4 का प्रयोग कर आप केवल 1 9 1 वर्ण (767/4 = 1 9 1) को स्टोर कर सकते हैं।

आप पूरी तरह से VARCHAR(255) फ़ील्ड utf8mb4 का उपयोग करने के लिए नियमित अनुक्रमित जोड़ सकते हैं, लेकिन क्या होता है सूचकांक आकार 1 9 1 वर्णों पर स्वचालित रूप से छोटा कर दिया जाता है – जैसे unique_key यहां:

सिक्वेल प्रो स्क्रीनशॉट दिखा रहा है 1 9 1 वर्णों में छोटा

यह ठीक है, क्योंकि नियमित अनुक्रमणिका सिर्फ अपने डेटा के माध्यम से और अधिक तेज़ी से MySQL खोज में सहायता के लिए उपयोग की जाती हैं पूरे क्षेत्र को अनुक्रमित करने की आवश्यकता नहीं है

इसलिए, क्यों MySQL स्वचालित रूप से नियमित अनुक्रमणिका के लिए सूचकांक को छोटा करता है, लेकिन अनदेखी इंडेक्स के लिए ऐसा करने की कोशिश में एक स्पष्ट त्रुटि फेंक सकता है? खैर, MySQL के लिए यह पता लगाने में सक्षम होना चाहिए कि मूल्य जो डाला या अपडेट किया जा रहा है, पहले से मौजूद है, यह वास्तव में पूरे मूल्य का सूचकांक होना चाहिए और उसका सिर्फ एक हिस्सा नहीं होना चाहिए।

दिन के अंत में, यदि आप किसी फ़ील्ड पर एक अद्वितीय इंडेक्स चाहते हैं, तो फ़ील्ड की संपूर्ण सामग्री को इंडेक्स में फिट होना चाहिए। Utf8mb4 के लिए, इसका मतलब है कि आपके VARCHAR फ़ील्ड लंबाई को 1 9 1 या उससे कम वर्णों तक कम करना। अगर आपको उस तालिका या फ़ील्ड के लिए utf8mb4 की आवश्यकता नहीं है, तो आप इसे utf8 पर वापस कर सकते हैं और अपने 255 लंबाई फ़ील्ड को रखने में सक्षम हो सकते हैं।

इस बात का जवाब है कि आपको कई बार यहां कई उपयोगकर्ताओं द्वारा त्रुटि संदेश क्यों प्राप्त हुआ है। मेरा जवाब तय है कि कैसे इसे ठीक करें और इसका प्रयोग करें जैसा कि हो।

इस लिंक से देखें

  1. MySQL क्लाइंट खोलें (या मारियाडाबी क्लाइंट)। यह एक कमांड लाइन टूल है
  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 पर अपने डेटाबेस पर जाएं या ऐसा आसान प्रबंधन के लिए। > डेटाबेस का चयन करें> तालिका संरचना देखें> संचालन टैब पर जाएं > DYNAMIC को ROW_FORMAT बदलें और परिवर्तन सहेजें।
  2. तालिका की संरचना टैब पर जाएं> अनोखा बटन पर क्लिक करें।
  3. किया हुआ। अब इसमें कोई त्रुटि नहीं होनी चाहिए

इस फिक्स की समस्या यह है कि अगर आप डीबी को दूसरे सर्वर पर निर्यात करते हैं (उदाहरण के लिए स्थानीय होस्ट से वास्तविक होस्ट तक) और आप उस सर्वर में MySQL कमांड लाइन का उपयोग नहीं कर सकते हैं आप इसे वहां काम नहीं कर सकते।

5.4। दस्तावेज़ीकरण के अनुसार ; आपको डिफ़ॉल्ट स्ट्रिंग की लंबाई को अंदर सेट करना होगा

बूट

उसकि विधि

एप्लिकेशन / प्रदाता / AppServiceProvider.php

फ़ाइल निम्नानुसार है:

 use Illuminate\Support\Facades\Schema; public function boot() { Schema::defaultStringLength(191); } 

अपने मिलान को बदल दें आप utf8_general_ci का उपयोग कर सकते हैं जो लगभग सभी का समर्थन करता है

नीचे दिया गया स्तंभ के आधार पर, उन 2 चर स्ट्रिंग कॉलम utf8_general_ci collation ( utf8 charset निहित है) का उपयोग कर रहे हैं।

MySQL में, utf8 वर्णसेट प्रत्येक वर्ण के लिए अधिकतम 3 बाइट्स का उपयोग करता है। इस प्रकार, यह 500 * 3 = 1500 बाइट आवंटित करने की आवश्यकता होगी, जो कि 767 बाइट्स से अधिक है, MySQL अनुमति देता है। यही कारण है कि आपको ये 1071 त्रुटि मिल रही है

दूसरे शब्दों में, आपको वर्णसेट के बाइट प्रतिनिधित्व के आधार पर वर्ण गिनती की गणना करने की आवश्यकता नहीं है क्योंकि प्रत्येक वर्णसेट एक एकल बाइट प्रतिनिधित्व नहीं है (जैसा कि आपने माना है।) MySQL में IE utf8 का उपयोग अधिकतम 3-बाइट प्रति वर्ण, 767/3 uses पर होता है 255 वर्ण, और utf8mb4 , एक अधिकतम 4-बाइट प्रतिनिधित्व, 767 / 4≈191 वर्ण।

यह भी ज्ञात है कि MySQL

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

मैंने इस विषय पर कुछ खोज को अंत में कुछ कस्टम परिवर्तन मिला

MySQL कार्यक्षेत्र 6.3.7 संस्करण के लिए ग्राफ़िकल अंतर चरण उपलब्ध है

  1. कार्यक्षेत्र शुरू करें और कनेक्शन का चयन करें।
  2. प्रबंधन या उदाहरण पर जाएं और विकल्प फ़ाइल चुनें।
  3. यदि वर्कबैंक आपको कॉन्फ़िगरेशन फ़ाइल को पढ़ने के लिए अनुमति देता है और फिर दो बार ठीक से दबाने की अनुमति देता है।
  4. केंद्र जगह पर प्रशासक विकल्प फ़ाइल विंडो आता है।
  5. InnoDB टैब पर जाएं और innodb_large_prefix की जांच करें यदि यह सामान्य अनुभाग में चेक नहीं किया गया है।
  6. डायनामिक के लिए innodb_default_row_format विकल्प मान सेट करें।

6.3.7 नीचे दिए गए संस्करणों के लिए सीधे विकल्प उपलब्ध नहीं हैं इसलिए कमांड प्रॉम्प्ट के साथ जाने की जरूरत है

  1. व्यवस्थापक के रूप में सीएमडी प्रारंभ करें
  2. निर्देशक पर जाएं जहां mysql सर्वर स्थापित है अधिकांश मामलों में "C: \ Program Files \ MySQL \ MySQL सर्वर 5.7 \ bin" पर ऐसा आदेश "cd \" "cd प्रोग्राम फ़ाइलें \ MySQL \ MySQL सर्वर 5.7 \ bin" है।
  3. अब रन कमांड mysql -u उपयोगकर्ता नाम -पी डाटाबेससेमा अब उसने संबंधित उपयोगकर्ता के पासवर्ड के लिए पूछा। पासवर्ड प्रदान करें और mysql संकेत में दर्ज करें।
  4. हमें कुछ वैश्विक सेटिंग्स को सेट करना होगा नीचे दिए गए कमांडों को एक सेट में एक सेट global innodb_large_prefix = on; सेट वैश्विक इनोसब_फाइल_फोर्म = बारकुका; सेट वैश्विक innodb_file_per_table = true;
  5. अब आखिरकार हमें आवश्यक तालिका के ROW_FORMAT को डिफ़ॉल्ट रूप से इसके कॉम्पेक्ट में बदलना होगा, हमें इसे डीनामी पर सेट करना होगा।
  6. निम्न कमांड का प्रयोग करें तालिका तालिका_नाम ROW_FORMAT = DYNAMIC;
  7. किया हुआ

मुझे यह क्वेरी पता लगाई गई थी कि कौन सा स्तंभ अधिकतम सूचकांक का उल्लंघन करता है:

 SELECT c.TABLE_NAME As TableName, c.COLUMN_NAME AS ColumnName, c.DATA_TYPE AS DataType, c.CHARACTER_MAXIMUM_LENGTH AS ColumnLength, s.INDEX_NAME AS IndexName FROM information_schema.COLUMNS AS c INNER JOIN information_schema.statistics AS s ON s.table_name = c.TABLE_NAME AND s.COLUMN_NAME = c.COLUMN_NAME WHERE c.TABLE_SCHEMA = DATABASE() AND c.CHARACTER_MAXIMUM_LENGTH > 191 AND c.DATA_TYPE IN ('char', 'varchar', 'text') 

"लैटिन 1" के लिए शिकायत सूचक फ़ील्ड के चार्ज बदलें
अर्थात् वैकल्पिक तालिका टीबीएल परिवर्तन मैरिफ़ेल्ड मैरीफल्ड varchar (600) वर्ण सेट latin1 DEFAULT NULL;
लैटिन 1 चार के बजाय एक चरित्र के लिए एक बाइट लेता है

कृपया जांच लें कि क्या sql_mode समान है – sql_mode = NO_ENGINE_SUBSTITUTION, STRICT_TRANS_TABLES

अगर यह है, तो परिवर्तन- sql_mode = NO_ENGINE_SUBSTITUTION

या

अपने सर्वर को अपनी my.cnf फ़ाइल बदलकर पुनरारंभ करें (डालने के बाद) –

innodb_large_prefix = पर

यदि आप कुछ ऐसा बना रहे हैं:

 CREATE TABLE IF NOT EXISTS your_table ( id int(7) UNSIGNED NOT NULL AUTO_INCREMENT, name varchar(256) COLLATE utf8mb4_bin NOT NULL, PRIMARY KEY (id), UNIQUE KEY name (name) ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED; 

यह कुछ ऐसा होना चाहिए

 CREATE TABLE IF NOT EXISTS your_table ( id int(7) UNSIGNED NOT NULL AUTO_INCREMENT, name varchar(256) COLLATE utf8mb4_bin NOT NULL, PRIMARY KEY (id) ) ENGINE=INNODB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=1 ROW_FORMAT=FIXED; 

लेकिन आपको कोड से उस कॉलम की विशिष्टता की जांच करने की आवश्यकता है या वर्चार कॉलम के एक MD5 या SHA1 के रूप में एक नया कॉलम जोड़ना

यदि आपने हाल ही में innodb_log_file_size बदल दिया है, तो पिछले मूल्य को पुनर्स्थापित करने का प्रयास करें जो काम किया।

यह मेरा मूल जवाब है:

मैं बस डेटाबेस को छोड़ देता हूं और इस तरह विश्राम करता हूं, और त्रुटि समाप्त हो गई है:

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

हालांकि, यह सभी मामलों के लिए काम नहीं करता है

यह वास्तव में VARCHAR स्तंभों पर वर्ण सेट utf8 (या utf8mb4 ) के साथ अनुक्रमित का उपयोग करने की एक समस्या है, जो कि VARCHAR कॉलम के साथ होती है जो वर्णों की एक निश्चित लंबाई से अधिक होती है। utf8mb4 के मामले में, यह निश्चित लंबाई 1 9 1 है।

अधिक जानकारी के लिए कृपया लंबे अनुक्रमांक का उपयोग कैसे करें MySQL डाटाबेस में http://hanoian.com/content/index.php/24-automate-the-converting-a-mysql-database- चरित्र सेट करने के लिए utf8mb4

मेरे लिए, "# 1071 का मुद्दा – निर्दिष्ट कुंजी बहुत लंबी थी, अधिकतम कुंजी लंबाई 767 बाइट्स" को प्राथमिक कुंजी / 20000 तक स्तंभ आकार को सीमित करके प्राथमिक कुंजी / अनिक्विक संयोजन बदलने के बाद हल किया गया।

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