MySQL की हिडन सुविधाएँ


101

मैं अब कई वर्षों के साथ Microsoft SQL सर्वर के साथ काम कर रहा हूं, लेकिन अभी हाल ही में अपने वेब अनुप्रयोगों के साथ MySQL का उपयोग करना शुरू कर दिया है , और मुझे ज्ञान की भूख है।

"छिपी हुई सुविधा" सवालों की लंबी लाइन के साथ जारी रखने के लिए , मैं MySQL की किसी भी छिपी या आसान विशेषताओं को जानना चाहूंगा जो इस खुले स्रोत डेटाबेस के बारे में मेरे ज्ञान को बेहतर बनाएगा।

जवाबों:


161

जब से तुम एक इनाम रखा है, मैं अपनी मुश्किल जीता रहस्य साझा करेंगे ...

सामान्य तौर पर, सभी एसक्यूएल जिन्हें मैंने आज उप-प्रश्नों का उपयोग करके आवश्यक किया था। Oracle डेटाबेस की दुनिया से आने के बाद, मैंने जो चीजें दीं, वे MySQL के साथ काम नहीं कर रही थीं। और MySQL ट्यूनिंग पर मेरा पढ़ना मुझे निष्कर्ष निकालता है कि प्रश्नों के अनुकूलन के मामले में MySQL Oracle के पीछे है।

जबकि अधिकांश बी 2 सी अनुप्रयोगों के लिए आवश्यक सरल प्रश्न MySQL के लिए अच्छी तरह से काम कर सकते हैं, अधिकांश रिपोर्टिंग रिपोर्टिंग प्रकार जो इंटेलिजेंस रिपोर्टिंग के लिए आवश्यक थे, के लिए एक उचित बिट की योजना बनाने और MySQL को तेजी से निष्पादित करने के लिए MySQL को निर्देशित करने के लिए फिर से व्यवस्थित करने की आवश्यकता प्रतीत होती है।

शासन प्रबंध:

max_connectionsसमवर्ती कनेक्शन की संख्या है। डिफ़ॉल्ट मान 100 कनेक्शन है (5.0 के बाद से 151) - बहुत छोटा।

ध्यान दें:

कनेक्शन मेमोरी लेते हैं और आपका OS बहुत सारे कनेक्शनों को संभालने में सक्षम नहीं हो सकता है।

लिनक्स / x86 के लिए MySQL बायनेरी आपको 4096 तक समवर्ती कनेक्शन की अनुमति देता है, लेकिन स्व संकलित बायनेरिज़ में अक्सर एक सीमा कम होती है।

अपनी खुली तालिकाओं और समवर्ती कनेक्शनों की संख्या के मिलान के लिए table_cache सेट करें। Open_tables मान देखें और यदि यह जल्दी से बढ़ रहा है तो आपको इसका आकार बढ़ाने की आवश्यकता होगी।

ध्यान दें:

पिछले 2 मापदंडों को बहुत सारी खुली फ़ाइलों की आवश्यकता हो सकती है। 20 + max_connections + table_cache * 2 जो आपके लिए आवश्यक है उसके लिए एक अच्छा अनुमान है। लिनक्स पर MySQL में एक open_file_limit विकल्प है, इस सीमा को सेट करें।

यदि आपके पास जटिल प्रश्न हैं Sort_buffer_size और tmp_table_size बहुत महत्वपूर्ण होने की संभावना है। मान क्वेरी जटिलता और उपलब्ध संसाधनों पर निर्भर करेगा, लेकिन 4Mb और 32Mb, क्रमशः शुरुआती बिंदुओं की सिफारिश की जाती है।

नोट: ये "प्रति कनेक्शन" मान हैं, read_buffer_size, read_rnd_buffer_size और कुछ अन्य लोगों के बीच, जिसका अर्थ है कि प्रत्येक कनेक्शन के लिए इस मान की आवश्यकता हो सकती है। इसलिए, इन मापदंडों को सेट करते समय अपने लोड और उपलब्ध संसाधन पर विचार करें। उदाहरण के लिए Sort_buffer_size केवल तभी आवंटित किया जाता है जब MySQL को एक सॉर्ट करने की आवश्यकता होती है। नोट: ध्यान रहे कि मेमोरी से बाहर न भागें।

यदि आपके पास कई कनेक्ट स्थापित हैं (यानी लगातार कनेक्शन के बिना एक वेब साइट), तो आप गैर-शून्य मान के लिए थ्रेड_cache_size सेट करके प्रदर्शन में सुधार कर सकते हैं। 16 के साथ शुरू करने के लिए अच्छा मूल्य है। मूल्य बढ़ाएं जब तक कि आपके थ्रेड्स_क्रिएटेड बहुत जल्दी नहीं बढ़ते हैं।

प्राथमिक कुंजी:

प्रति तालिका में केवल एक AUTO_INCREMENT कॉलम हो सकता है, इसे अनुक्रमित किया जाना चाहिए, और इसमें DEFAF मान नहीं हो सकता

कुंजी आमतौर पर INDEX का पर्याय है। मुख्य विशेषता प्राथमिक कुंजी को कॉलम परिभाषा में दिए जाने पर सिर्फ कुंजी के रूप में निर्दिष्ट किया जा सकता है। यह अन्य डेटाबेस सिस्टम के साथ संगतता के लिए लागू किया गया था।

एक प्राथमिक कुंजी एक अद्वितीय सूचकांक है, जहां सभी प्रमुख कॉलमों को नॉट NULL के रूप में परिभाषित किया जाना चाहिए

यदि एक प्राथमिक कुंजी या UNIQUE इंडेक्स में केवल एक कॉलम होता है जिसमें पूर्णांक प्रकार होता है, तो आप सेलेक्ट स्टेटमेंट में कॉलम को "_rowid" के रूप में भी संदर्भित कर सकते हैं।

MySQL में, PRIMARY KEY का नाम PRIMARY है

वर्तमान में, केवल InnoDB (v5.1?) टेबल विदेशी कुंजी का समर्थन करते हैं।

आमतौर पर, आप उन सभी इंडेक्सों को बनाते हैं जिनकी आपको आवश्यकता होती है जब आप टेबल बना रहे होते हैं। किसी भी कॉलम को PRIMARY KEY, KEY, UNIQUE या INDEX के रूप में घोषित किया जाएगा।

NULL का अर्थ है "मूल्य नहीं होना"। NULL के लिए परीक्षण करने के लिए, आप अंकगणितीय तुलना ऑपरेटरों जैसे =, <, या <> का उपयोग नहीं कर सकते । इसके बजाय IS NULL और IS NULL ऑपरेटरों का उपयोग करें:

NO_AUTO_VALUE_ON_ZERO 0 के लिए ऑटो वेतन वृद्धि को दबाता है ताकि केवल NULL अगला अनुक्रम संख्या उत्पन्न करे। यह मोड उपयोगी हो सकता है यदि 0 को किसी तालिका के AUTO_INCREMENT कॉलम में संग्रहीत किया गया हो। (भंडारण 0 अनुशंसित तरीका नहीं है।)

नई पंक्तियों के लिए उपयोग किए जाने वाले AUTO_INCREMENT काउंटर का मान बदलने के लिए:

ALTER TABLE mytable AUTO_INCREMENT = value; 

या INSERT_ID = मान सेट करें;

जब तक अन्यथा निर्दिष्ट नहीं किया जाता है, तब तक मूल्य इस प्रकार होगा: 1000000 या इसे इस प्रकार निर्दिष्ट करें:

...) इंजन = MyISAM डिफाल्ट चार्ट = लैटिन 1 AUTO_INCREMENT = 1

timestamps:

TIMESTAMP स्तंभों का मान संग्रहण के लिए वर्तमान समय क्षेत्र से UTC में और UTC से वर्तमान समय क्षेत्र में पुनर्प्राप्ति के लिए परिवर्तित किया जाता है।

http://dev.mysql.com/doc/refman/5.1/en/timestamp.html किसी तालिका में एक TIMESTAMP स्तंभ के लिए, आप वर्तमान टाइमस्टैम्प को डिफ़ॉल्ट मान और स्वतः-अद्यतन मान के रूप में असाइन कर सकते हैं।

WHERE क्लॉज़ में इन प्रकारों में से किसी एक का उपयोग करते समय देखने के लिए एक बात, WHERE datecolumn = FROM_UNIXTIME (1057941242) करना सबसे अच्छा है और न कि जहाँ UNIX_TIMESTAMP (दिनांक) = 1057941242 है। बाद वाले इंडेक्स का लाभ नहीं लेंगे उस कॉलम पर।

http://dev.mysql.com/doc/refman/5.1/en/date-and-time-functions.html

 UNIX_TIMESTAMP() 
 FROM_UNIXTIME() 
 UTC_DATE()
 UTC_TIME()
 UTC_TIMESTAMP()

यदि आप MySQL में यूनिक्स टाइमस्टैम्प में एक डेटाइम को कनवर्ट करते हैं:
और फिर इसमें 24 घंटे जोड़ते हैं:
और फिर इसे वापस एक डेटाइम में परिवर्तित करें यह जादुई रूप से एक घंटा खो देता है!

यहाँ क्या हो रहा है। जब यूनिक्स टाइमस्टैम्प को एक डाइमटाइम में वापस परिवर्तित किया जाता है, तो समय-सीमा को ध्यान में रखा जाता है और यह सिर्फ इतना होता है कि 28 और 29 अक्टूबर 2006 के बीच हम दिन के उजाले की बचत के समय से चले गए और एक घंटा खो गए।

MySQL 4.1.3 से शुरू होकर, CURRENT_TIMESTAMP (), CURRENT_TIME (), CURRENT_DATE (), और FROM_UNIXTIME () फ़ंक्शन कनेक्शन के वर्तमान समय क्षेत्र में मान लौटाते हैं , जो time_zone सिस्टम चर के मान के रूप में उपलब्ध है। इसके अलावा, UNIX_TIMESTAMP () मानता है कि इसका तर्क वर्तमान समय क्षेत्र में एक डेटटाइम मान है।

वर्तमान समय क्षेत्र सेटिंग UTC_TIMESTAMP () या DATE, TIME, या DATETIME कॉलम जैसे मानों से प्रदर्शित मानों को प्रभावित नहीं करती है।

नोट: यदि अद्यतन किया जाता है तो केवल दिनांक समय-सारणी अपडेट करें यदि फ़ील्ड बदली गई है तो यदि कोई अद्यतन फ़ील्ड नहीं बदली जा रही है तो दिनांक समय अद्यतन नहीं है!

अतिरिक्त रूप से, पहला टाइमस्टैम्प हमेशा डिफ़ॉल्ट रूप से स्वचालित होता है, भले ही वह निर्दिष्ट न हो

जब मैं डेट्स के साथ काम करता हूं, तो मैं लगभग हमेशा जूलियन डेट बीसूएज़ डेटा गणित से अवगत कराता हूं, फिर एक ही कारण के लिए आधी रात के बाद से पूर्णांकों को जोड़ने और अधीन करने का एक साधारण मामला है। यह दुर्लभ है कि मुझे सेकंड की तुलना में बारीक बारीकता के समय पुनर्जीवन की आवश्यकता है।

इन दोनों को एक 4 बाइट पूर्णांक के रूप में संग्रहीत किया जा सकता है, और यदि अंतरिक्ष वास्तव में तंग है तो UNIX समय (सेकंड 1/1/1970 के बाद से) को एक अहस्ताक्षरित पूर्णांक के रूप में जोड़ा जा सकता है जो लगभग 2106 तक अच्छा होगा:

'मुद्राओं में सेकंड = 86400

'हस्ताक्षर किए गए पूर्णांक अधिकतम वैल = 2,147,483,647 - सेकेंड के 68 वर्ष हो सकते हैं

'अनसाइनड इंटेगर मैक्स वैल = 4,294,967,295 - 136 साल के सेकंड्स को होल्ड कर सकता है

बाइनरी प्रोटोकॉल:

MySQL 4.1 ने एक बाइनरी प्रोटोकॉल पेश किया है जो गैर-स्ट्रिंग डेटा मानों को भेजने और स्ट्रिंग प्रारूप से रूपांतरण के बिना मूल प्रारूप में वापस भेजने की अनुमति देता है। (बहुत उपयोगी)

इसके अलावा, mysql_real_query () mysql_query () से तेज है क्योंकि यह स्टेटीन स्ट्रिंग पर काम करने के लिए स्ट्रलेन () को कॉल नहीं करता है।

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html बाइनरी प्रोटोकॉल सर्वर-साइड तैयार कथनों का समर्थन करता है और देशी प्रारूप में डेटा मूल्यों के प्रसारण की अनुमति देता है। MySQL 4.1 के पहले रिलीज के दौरान बाइनरी प्रोटोकॉल में काफी सुधार हुआ।

आप यह परीक्षण करने के लिए IS_NUM () मैक्रो का उपयोग कर सकते हैं कि किसी फ़ील्ड का संख्यात्मक प्रकार है या नहीं। IS_NUM () के प्रकार का मान पास करें और फ़ील्ड के संख्यात्मक होने पर यह TRUE का मूल्यांकन करता है:

टिप्पणी करने के लिए एक बात है कि बाइनरी डेटा है सकते हैं एक नियमित रूप से क्वेरी के अंदर भेजा जा अगर आप इसे से बचने और याद MySQL की आवश्यकता है केवल कि बैकस्लैश और उद्धरण कैरेक्टर भाग निकले जा। उदाहरण के लिए एन्क्रिप्टेड / नमकीन पासवर्ड जैसे छोटे बाइनरी स्ट्रिंग्स को INSERT करना वास्तव में आसान तरीका है।

मास्टर सर्वर:

http://www.experts-exchange.com/Database/MySQL/Q_22967482.html

http://www.databasejournal.com/features/mysql/article.php/10897_3355201_2

अनुदान की प्रतिपूर्ति 'गुलाम_पासवर्ड' द्वारा

#Master Binary Logging Config  STATEMENT causes replication 
              to be statement-based -  default

log-bin=Mike
binlog-format=STATEMENT
server-id=1            
max_binlog_size = 10M
expire_logs_days = 120    


#Slave Config
master-host=master-hostname
master-user=slave-user
master-password=slave-password
server-id=2

बाइनरी लॉग फ़ाइल अवश्य पढ़ें:

http://dev.mysql.com/doc/refman/5.0/en/binary-log.html

http://www.mydigitallife.info/2007/10/06/how-to-read-mysql-binary-log-files-binlog-with-mysqlbinlog/

http://dev.mysql.com/doc/refman/5.1/en/mysqlbinlog.html

http://dev.mysql.com/doc/refman/5.0/en/binary-log.html

http://dev.mysql.com/doc/refman/5.1/en/binary-log-setting.html

आप RESET MASTER स्टेटमेंट के साथ सभी बाइनरी लॉग फ़ाइलों को हटा सकते हैं, या PURGE MASTER के साथ उन्हें एक सबसेट कर सकते हैं

--result-file = binlog.txt TrustedFriend-bin.000030

सामान्यीकरण:

http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html

यूडीएफ कार्य करता है

http://www.koders.com/cpp/fid10666379322B54AD41AEB0E4100D87C8CDDF1D8C.aspx

http://souptonuts.sourceforge.net/readme_mysql.htm

जानकारी का प्रकार:

http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html

http://www.informit.com/articles/article.aspx?p=1238838&seqNum=2

http://bitfilm.net/2008/03/24/saving-bytes-efficient-data-storage-mysql-part-1/

एक बात का ध्यान रखें कि CHAR और VARCHAR दोनों के साथ एक मिश्रित टेबल पर, mySQL CHAR के VARCHAR में बदल जाएगा

RecNum integer_type UNULLIGNED नहीं पूर्ण AUTO_INCREMENT, प्राथमिक कुंजी (RecNum)

MySQL हमेशा मानक SQL और ISO 8601 विनिर्देशों के अनुसार, पहले वर्ष के साथ तारीखों का प्रतिनिधित्व करता है

विविध:

कुछ MySQl कार्यक्षमता को बंद करने के परिणामस्वरूप छोटी डेटा फ़ाइलें और तेज़ी से पहुंच प्राप्त होगी। उदाहरण के लिए:

-डाटाडिर डेटा डायरेक्टरी और निर्दिष्ट करेगा

-स्काइप-इनोडब इनो विकल्प को बंद कर देगा और आपको 10-20M बचाएगा

यहाँ और अधिक http://dev.mysql.com/tech-resources/articles/mysql-c-api.html

डाउनलोड अध्याय 7 - नि: शुल्क

InnoDB ट्रांसेक्शनल है, लेकिन एक प्रदर्शन ओवरहेड है जो इसके साथ आता है। मैंने अपनी परियोजनाओं के 90% के लिए MyISAM तालिकाओं को पर्याप्त पाया है। गैर-लेन-देन-सुरक्षित टेबल (MyISAM) के अपने स्वयं के कई फायदे हैं, जो सभी के कारण होते हैं:

कोई लेनदेन ओवरहेड नहीं है:

काफी तेज

कम डिस्क स्थान आवश्यकताएँ

अपडेट करने के लिए कम मेमोरी की आवश्यकता होती है

प्रत्येक MyISAM तालिका को डिस्क पर तीन फ़ाइलों में संग्रहीत किया जाता है। फ़ाइलों में नाम होते हैं जो तालिका नाम से शुरू होते हैं और फ़ाइल प्रकार को इंगित करने के लिए एक एक्सटेंशन होता है। एक .frm फ़ाइल तालिका प्रारूप को संग्रहीत करती है। डेटा फ़ाइल में एक .MYD (MYData) एक्सटेंशन है। सूचकांक फ़ाइल में एक .MYI (MYIndex) एक्सटेंशन है।

MySQL एडमिनिस्ट्रेटर बैकअप सुविधा का उपयोग किए बिना इन फ़ाइलों को स्टोरेज लोकेशन पर कॉपी किया जा सकता है, जो समय लेने वाली है (ताकि रिस्टोर हो)

ट्रिक इन फाइल्स की एक कॉपी बना लेती है फिर टेबल को DROP कर देती है। जब आप फ़ाइलों को वापस डालते हैं तो MySQl उन्हें पहचान लेगा और टेबल ट्रैकिंग को अपडेट कर देगा।

यदि आपको बैकअप / पुनर्स्थापना चाहिए,

बैकअप को पुनर्स्थापित करना, या किसी मौजूदा डंप फ़ाइल से आयात करना प्रत्येक तालिका पर आपके द्वारा अनुक्रमित और प्राथमिक कुंजियों की संख्या के आधार पर एक लंबा समय ले सकता है। आप इस प्रक्रिया को नाटकीय रूप से अपनी मूल डंप फ़ाइल को संशोधित करके इसे आसपास के साथ गति दे सकते हैं:

SET AUTOCOMMIT = 0;
SET FOREIGN_KEY_CHECKS=0;

.. your dump file ..

SET FOREIGN_KEY_CHECKS = 1;
COMMIT;
SET AUTOCOMMIT = 1;

पुनः लोड की गति को बढ़ाने के लिए, SQL कमांड SET AUTOCOMMIT = 0 जोड़ें; डंप फ़ाइल की शुरुआत में, और COMMIT जोड़ें; अंत तक आज्ञा।

डिफ़ॉल्ट रूप से, ऑटोकॉमिट चालू है, जिसका अर्थ है कि डंप फ़ाइल में प्रत्येक और सम्मिलित कमांड को एक अलग लेनदेन के रूप में माना जाएगा और अगले एक को शुरू करने से पहले डिस्क पर लिखा जाएगा। यदि आप इन आदेशों को नहीं जोड़ते हैं, तो एक बड़े डेटाबेस को InnoDB में पुनः लोड करने में कई घंटे लग सकते हैं ...

MySQL तालिका में एक पंक्ति का अधिकतम आकार 65,535 बाइट्स है

MySQL 5.0.3 में और VARCHAR की प्रभावी अधिकतम लंबाई = अधिकतम पंक्ति आकार (65,535 बाइट्स)

VARCHAR मान संग्रहीत नहीं किए जाते हैं। मानक एसक्यूएल के अनुरूप मूल्यों को संग्रहीत और पुनर्प्राप्त किए जाने पर ट्रेलिंग स्पेस को बनाए रखा जाता है।

MySQL में CHAR और VARCHAR मान को अनुगामी रिक्त स्थान की परवाह किए बिना तुलना की जाती है।

यदि पूरा रिकॉर्ड निश्चित आकार का है, तो CHAR का उपयोग करने से आपकी पहुंच में तेजी आएगी। यही है, यदि आप किसी भी चर आकार की वस्तु का उपयोग करते हैं, तो आप उन सभी को भी चर आकार दे सकते हैं। आप किसी तालिका में CHAR का उपयोग करके कोई गति प्राप्त नहीं करते हैं जिसमें VARCHAR भी शामिल है।

255 वर्णों की VARCHAR सीमा MySQL 5.0.3 के रूप में 65535 वर्णों तक बढ़ाई गई थी

पूर्ण-पाठ खोज केवल MyISAM तालिकाओं के लिए समर्थित हैं।

http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html

BLOB कॉलम में कोई वर्ण सेट नहीं है, और स्तंभ मानों में बाइट्स के संख्यात्मक मानों के आधार पर छंटनी और तुलना होती है

यदि सख्त SQL मोड सक्षम नहीं है और आप एक BLOB या TEXT कॉलम के मान को असाइन करते हैं जो कॉलम की अधिकतम लंबाई से अधिक है, तो मान को फिट करने के लिए छोटा कर दिया जाता है और एक चेतावनी उत्पन्न होती है।

उपयोगी कमांड:

सख्त मोड की जाँच करें: SELECT @@ global.sql_mode;

सख्त मोड बंद करें:

SET @@ global.sql_mode = '';

SET @@ global.sql_mode = 'MYSQL40'

या निकालें: sql-mode = "STRICT_TRANS_TABLES, ...

रंगों से दिखाएँ mytable

Virtualcolumn virtualcolumnद्वारा mytable ORDER से अधिकतम (namecount) का चयन करें

http://dev.mysql.com/doc/refman/5.0/en/group-by-hidden-fields.html

http://dev.mysql.com/doc/refman/5.1/en/information-functions.html#function_last-insert-id last_insert_id ()

आपको वर्तमान थ्रेड अधिकतम (pkcolname) में सम्मिलित अंतिम पंक्ति का PK मिलता है, जो आपको अंतिम PK समग्र रूप से मिलता है।

नोट: यदि तालिका खाली है अधिकतम (pkcolname) 1 mysql_insert_id () मूल MySQL C API फ़ंक्शन mysql_insert_id () के एक प्रकार के लंबे (PHP में नामित नाम) के रिटर्न प्रकार को धर्मान्तरित करता है।

यदि आपके AUTO_INCREMENT कॉलम में BIGINT का कॉलम है, तो mysql_insert_id () द्वारा लौटाया गया मान गलत होगा। इसके बजाय, SQL क्वेरी में आंतरिक MySQL SQL फ़ंक्शन LAST_INSERT_ID () का उपयोग करें।

http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

बस ध्यान दें कि जब आप तालिका में डेटा सम्मिलित करने का प्रयास कर रहे हों और आपको त्रुटि मिले:

Unknown column the first bit of data what you want to put into the table in field list

जैसे कुछ का उपयोग कर

INSERT INTO table (this, that) VALUES ($this, $that)

ऐसा इसलिए है क्योंकि जिन मूल्यों को आप तालिका में रखने की कोशिश कर रहे हैं, उनके आसपास आपको कोई एपोस्ट्रोफ नहीं मिला है। इसलिए आपको अपना कोड इसमें बदलना चाहिए:

INSERT INTO table (this, that) VALUES ('$this', '$that') 

याद दिलाएं कि `` का उपयोग MySQL फ़ील्ड्स, डेटाबेस या तालिकाओं को परिभाषित करने के लिए किया जाता है, मूल्यों पर नहीं;)

क्वेरी के दौरान सर्वर से कनेक्शन खो गया:

http://dev.mysql.com/doc/refman/5.1/en/gone-away.html

http://dev.mysql.com/doc/refman/5.1/en/packet-too-large.html

http://dev.mysql.com/doc/refman/5.0/en/server-parameters.html

http://dev.mysql.com/doc/refman/5.1/en/show-variables.html

http://dev.mysql.com/doc/refman/5.1/en/option-files.html

http://dev.mysql.com/doc/refman/5.1/en/error-log.html

ट्यूनिंग क्वेरी

http://www.artfulsoftware.com/infotree/queries.php?&bw=1313

अच्छा है कि मुझे लगता है कि बोनस कमाने के लिए पर्याप्त होना चाहिए ... एक महान मुक्त डेटाबेस के साथ कई घंटे और कई परियोजनाओं के फल । मैं ज्यादातर MySQL के साथ विंडोज़ प्लेटफार्मों पर एप्लिकेशन डेटा सर्वर विकसित करता हूं। मुझे जो सबसे ज्यादा गड़बड़ करनी थी वह थी

परम MySQL विरासत डेटाबेस दुःस्वप्न

इसके लिए तालिकाओं की एक श्रृंखला की आवश्यकता होती है ताकि यहां बताए गए कई ट्रिक्स का उपयोग करके तालिकाओं को किसी उपयोगी वस्तु में संसाधित किया जा सके।

यदि आपको यह आश्चर्यजनक मददगार लगा, तो इसे वोट करके अपना धन्यवाद व्यक्त करें।

इसके अलावा मेरे अन्य लेख और श्वेत पत्र देखें: www.coastrd.com


22

MySQL की इतनी छुपी हुई विशेषता में से एक यह नहीं है कि यह वास्तव में SQL आज्ञाकारी होने पर अच्छा नहीं है, ठीक है, वास्तव में बग नहीं, लेकिन, और अधिक getchas ... :-)


लेटिंग्स अन्य जानते हैं कि MSSQL से MySQL में जाने पर यह सूची मूल्यवान है। चीयर्स मैट।
गेटकिलर

उन गोचरों में से कई MySQL के पुराने संस्करणों से हैं।
jmucchiello

एक के लिए, मुझे नहीं लगता कि टाइमस्टैम्प क्षेत्र में कभी भी NULL वैल्यू डालना संभव नहीं होगा।
चटाई

3
MySQL कई अन्य डेटाबेस की तुलना में SQL-आज्ञाकारी होने पर विशेष रूप से बदतर नहीं है; जब तक आप SQL के एक उप सबसेट से चिपक जाते हैं तब तक आप आम तौर पर गोच से बच सकते हैं - जो कि उदाहरण के लिए कहा जा सकता है। Oracle का बदनाम NULL खाली तार।
bobince

1
आप SET SESSION sql_mode='ANSI';
कोर्नेल

21

कैश में वर्तमान में क्या टेबल हैं, यह जानने के लिए एक कमांड:

mysql> SHOW open TABLES FROM test;
+----------+-------+--------+-------------+
| DATABASE | TABLE | In_use | Name_locked |
+----------+-------+--------+-------------+
| test     | a     |      3 |           0 |
+----------+-------+--------+-------------+
1 row IN SET (0.00 sec)

( MySQL प्रदर्शन ब्लॉग से )


15

यह पता लगाने के लिए कि कौन क्या कर रहा है:

mysql> show processlist;
show processlist;
+----+-------------+-----------------+------+---------+------+----------------------------------+------------------+
| Id | User        | Host            | db   | Command | Time | State                            | Info             |
+----+-------------+-----------------+------+---------+------+----------------------------------+------------------+
|  1 | root        | localhost:32893 | NULL | Sleep   |    0 |                                  | NULL             |
|  5 | system user |                 | NULL | Connect |   98 | Waiting for master to send event | NULL             |
|  6 | system user |                 | NULL | Connect | 5018 | Reading event from the relay log | NULL             |
+-----+------+-----------+---------+---------+-------+-------+------------------+
3 rows in set (0.00 sec) 

और आप के साथ एक प्रक्रिया को मार सकते हैं:

mysql>kill 5 

5
यदि आप प्रश्नों को छोटा नहीं करना चाहते हैं, तो पूरी प्रक्रिया को भी देखें।
ग्रेग

11

मुझे विशेष रूप से MySQL का अंतर्निहित समर्थन inet_ntoa()और पसंद है inet_aton()। यह तालिकाओं में IP पतों को बहुत सीधा (कम से कम इतना लंबा है कि वे केवल IPv4 पते हैं!)


2
PostgreSQL एक बहुत अच्छा मंत्रिमंडल प्रकार है, जो हैंडल IPv4 और IPv6 बहुत nicelly :-) है
चटाई

मैं भी उन्हें पसंद करता था, लेकिन उनका इस्तेमाल नहीं करना और भी बेहतर है। Postgres के लिए +1।
कोर्नेल

11

मैं on duplicate keyसभी प्रकार के काउंटरों के लिए लव (AKA अपटार्स, मर्ज) बनाता हूँ :

insert into occurances(word,count) values('foo',1),('bar',1) 
  on duplicate key cnt=cnt+1

आप एक क्वेरी में कई पंक्तियों को सम्मिलित कर सकते हैं, और तुरंत प्रत्येक पंक्तियों के लिए डुप्लिकेट इंडेक्स को संभाल सकते हैं।


10

फिर से - वास्तव में छिपी हुई विशेषताएं नहीं, लेकिन वास्तव में आसान:

फ़ीचर

आसानी से डीडीएल को पकड़ो:

SHOW CREATE TABLE CountryLanguage

उत्पादन:

CountryLanguage | CREATE TABLE countrylanguage (
  CountryCode char(3) NOT NULL DEFAULT '',
  Language char(30) NOT NULL DEFAULT '',
  IsOfficial enum('T','F') NOT NULL DEFAULT 'F',
  Percentage float(4,1) NOT NULL DEFAULT '0.0',
  PRIMARY KEY (CountryCode,Language)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

फ़ीचर: GROUP_CONCAT () एग्रीगेट फंक्शन अपने तर्कों के एक संक्षिप्त स्ट्रिंग को विस्तार से बनाता है, और एग्रीगेट्स को प्रति समूह को समेट कर।

उदाहरण 1: सरल

SELECT   CountryCode
,        GROUP_CONCAT(Language) AS List
FROM     CountryLanguage
GROUP BY CountryCode             

आउटपुट:

+-------------+------------------------------------+
| CountryCode | List                               |
+-------------+------------------------------------+
| ABW         | Dutch,English,Papiamento,Spanish   |
. ...         . ...                                .
| ZWE         | English,Ndebele,Nyanja,Shona       |
+-------------+------------------------------------+

उदाहरण 2: कई तर्क

SELECT   CountryCode
,        GROUP_CONCAT(
             Language
,            IF(IsOfficial='T', ' (Official)', '')
         )               AS List
FROM     CountryLanguage
GROUP BY CountryCode

आउटपुट:

+-------------+---------------------------------------------+
| CountryCode | List                                        |
+-------------+---------------------------------------------+
| ABW         | Dutch (Official),English,Papiamento,Spanish |
. ...         . ...                                         .
| ZWE         | English (Official),Ndebele,Nyanja,Shona     |
+-------------+---------------------------------------------+

उदाहरण 3: एक कस्टम विभाजक का उपयोग करना

SELECT   CountryCode
,        GROUP_CONCAT(Language SEPARATOR ' and ') AS List
FROM     CountryLanguage
GROUP BY CountryCode

आउटपुट:

+-------------+----------------------------------------------+
| CountryCode | List                                         |
+-------------+----------------------------------------------+
| ABW         | Dutch and English and Papiamento and Spanish |
. ...         . ...                                          .
| ZWE         | English and Ndebele and Nyanja and Shona     |
+-------------+----------------------------------------------+

उदाहरण 4: सूची तत्वों के क्रम को नियंत्रित करना

SELECT   CountryCode
,        GROUP_CONCAT(
         Language
         ORDER BY CASE IsOfficial WHEN 'T' THEN 1 ELSE 2 END DESC
         ,        Language
         )               AS List
FROM     CountryLanguage
GROUP BY CountryCode

आउटपुट:

+-------------+------------------------------------+
| CountryCode | List                               |
+-------------+------------------------------------+
| ABW         | English,Papiamento,Spanish,Dutch,  |
. ...         . ...                                .
| ZWE         | Ndebele,Nyanja,Shona,English       |
+-------------+------------------------------------+

फ़ीचर: कई भावों के साथ COUNT (DISTINCT)

संयोजनों की संख्या की गणना करने के लिए आप एक COUNT (DISTINCT ...) अभिव्यक्ति में कई अभिव्यक्तियों का उपयोग कर सकते हैं।

SELECT COUNT(DISTINCT CountryCode, Language) FROM CountryLanguage

फ़ीचर / गोच्टा: ग्रुप बीवाई सूची में गैर-एग्रीगेटेड भावों को शामिल करने की आवश्यकता नहीं है

अधिकांश RDBMS-es एक SQL92 आज्ञाकारी समूह को लागू करते हैं, जिसके लिए समूह BY में प्रदर्शित होने के लिए चयन सूची में सभी गैर-एकत्रित अभिव्यक्तियों की आवश्यकता होती है। इन RDBMS-es में, यह कथन:

SELECT     Country.Code, Country.Continent, COUNT(CountryLanguage.Language)
FROM       CountryLanguage 
INNER JOIN Country 
ON         CountryLanguage.CountryCode = Country.Code
GROUP BY   Country.Code

मान्य नहीं है, क्योंकि SELECT लिस्ट में नॉन-एग्रीगेटेड कॉलम Country.Continent है जो GROUP BY लिस्ट में दिखाई नहीं देता है। इन RDBMS-es में, आपको पढ़ने के लिए या तो GROUP BY सूची को संशोधित करना होगा

GROUP BY   Country.Code, Country.Continent

या आपको उदाहरण के लिए, कंट्री के लिए कुछ गैर-अर्थ कुल जोड़ना होगा

SELECT     Country.Code, MAX(Country.Continent), COUNT(CountryLanguage.Language)

अब, बात यह है कि, तार्किक रूप से ऐसा कुछ भी नहीं है जो मांग करता है कि Country.Continent को बढ़ाना चाहिए। देखें, Country.Code देश की तालिका की प्राथमिक कुंजी है। कंट्री.कंटेन्ट भी देश तालिका से एक स्तंभ है और इस प्रकार प्राथमिक कुंजी देश पर कार्यात्मक रूप से निर्भर परिभाषाओं के अनुसार है। कोड। इसलिए, देश में बिलकुल एक मूल्य मौजूद होना चाहिए। प्रत्येक अलग देश के लिए अलग। अगर आपको यह महसूस होता है कि, आपको एहसास है कि इसे एकत्र करने का कोई मतलब नहीं है (इसका सिर्फ एक मूल्य है, सही है) और न ही इसके द्वारा समूह बनाने के लिए (क्योंकि यह परिणाम को और अधिक अद्वितीय नहीं बनाएगा क्योंकि आप पहले से ही समूह बना रहे हैं पीके)

वैसे भी - MySQL आपको बिना चयन किए सूची में गैर-एकत्रित कॉलम को शामिल करने की अनुमति देता है, ताकि आप उन्हें ग्रुप BY क्लॉज में भी जोड़ सकें।

इस के साथ गेटा यह है कि यदि आप एक गैर-एकत्रित कॉलम का उपयोग करने के मामले में MySQL आपकी रक्षा नहीं करते हैं। तो, इस तरह एक क्वेरी:

SELECT     Country.Code, COUNT(CountryLanguage.Language), CountryLanguage.Percentage
FROM       CountryLanguage 
INNER JOIN Country 
ON         CountryLanguage.CountryCode = Country.Code
GROUP BY   Country.Code

शिकायत के बिना निष्पादित किया जाएगा, लेकिन CountryLanguage.Percentage कॉलम में गैर-समझ होगी (अर्थात, सभी भाषाओं के प्रतिशत की, प्रतिशत के लिए उपलब्ध मानों में से एक को यादृच्छिक या कम से कम आपके नियंत्रण से बाहर उठाया जाएगा।

देखें: मिथकों द्वारा सामूहिक समूह


समूह द्वारा घोषित नहीं किए जाने वाले स्तंभों की अनुमति ओरेकल से आने वाली मेरी सबसे कम पसंदीदा विशेषताओं में से एक है। यदि आप Oracle के लिए उपयोग किए जाते हैं तो यह एक बड़ा गोच है - यह आपको क्वेरी चलाने की अनुमति देता है, परिणाम सही दिखते हैं, लेकिन फिर आपको एहसास होता है कि यह वह नहीं कर रहा है जो आपने सोचा था कि यह था।
mbafford

7

क्लाइंट में "पेजर" कमांड

अगर आपको मिल गया है, तो कहिए, आपके परिणाम में 10,000 पंक्तियाँ हैं और उन्हें देखना चाहते हैं (यह "कम" और "टी" कमांड को उपलब्ध करता है, जो सामान्य रूप से लिनक्स के अंतर्गत होता है; विंडोज YMMV में)

pager less
select lots_of_stuff FROM tbl WHERE clause_which_matches_10k_rows;

और आप उन्हें "कम" फ़ाइल दर्शक में प्राप्त करेंगे ताकि आप उन्हें अच्छी तरह से खोज, आदि के माध्यम से पृष्ठ कर सकें।

भी

pager tee myfile.txt
select a_few_things FROM tbl WHERE i_want_to_save_output_to_a_file;

आसानी से एक फ़ाइल के लिए लिखेंगे।


दुर्भाग्य से खिड़कियों के नीचे, भले ही "कम" और "टी" मौजूद हों, पेजर विकल्प ही समर्थित नहीं है। वैसे भी आसानी से नहीं
बेरी तिकाला

6

कुछ चीजें आपको दिलचस्प लग सकती हैं:

<query>\G -- \G in the CLI instead of the ; will show one column per row
explain <query>; -- this will show the execution plan for the query


3

यहाँ मेरे कुछ सुझाव दिए गए हैं - मैंने अपने ब्लॉग में उनके बारे में ब्लॉग किया है ( लिंक )

  1. चर घोषित करते समय आपको '@' चिह्न का उपयोग करने की आवश्यकता नहीं है।
  2. आपको एक बयान के अंत को सीमांकित करने के लिए एक सीमांकक (डिफ़ॉल्ट है ';') का उपयोग करना होगा - लिंक
  3. यदि आप MS-SQL 2005 और mySQL के बीच डेटा को स्थानांतरित करने का प्रयास कर रहे हैं, तो लिंक के माध्यम से कूदने के लिए कुछ हुप्स हैं
  4. MySQL - लिंक में केस सेंसिटिव मैच करना


3

यदि cmdline Mysq का उपयोग कर रहे हैं, तो आप shriek / विस्मयादिबोधक चिह्न का उपयोग करके कमांड लाइन (लिनक्स मशीनों पर - अगर विंडोज पर एक समान प्रभाव हो तो निश्चित नहीं है) के साथ बातचीत कर सकते हैं। उदाहरण के लिए:

\! cat file1.sql

file1.sql के लिए कोड प्रदर्शित करेगा। अपने कथन और क्वेरी को फ़ाइल में सहेजने के लिए, टी सुविधा का उपयोग करें

\T filename

इसे बंद करने के लिए \ t का उपयोग करें

अंत में एक स्क्रिप्ट चलाने के लिए जिसे आपने पहले ही सहेजा है, "स्रोत फ़ाइलनाम" का उपयोग करें। बेशक, सामान्य विकल्प स्क्रिप्ट नाम में निर्देशित करने के लिए है जब कमांड लाइन से mysql शुरू होता है:

    mysql -u root -p < case1.sql

आशा है कि किसी के लिए उपयोग की है!

संपादित करें: बस एक और याद है - जब आप कमांड लाइन से mysql का उपयोग कर रहे हैं, तो आप -t स्विच का उपयोग कर सकते हैं ताकि आउटपुट तालिका प्रारूप में हो - कुछ प्रश्नों के साथ एक वास्तविक वरदान (हालांकि \ G के साथ प्रश्नों को समाप्त करना जैसा कि यहां कहीं भी उल्लेख किया गया है) इस संबंध में मददगार)। विभिन्न स्विच कमांड लाइन टूल पर बहुत अधिक

एक प्रकार के क्रम को बदलने के लिए बस एक साफ तरीका पाया गया (सामान्य रूप से केस का उपयोग करें ...) यदि आप एक प्रकार के क्रम को बदलना चाहते हैं (शायद 1, 2, 3 के बजाय 1, 4, 3, 2 के आधार पर छाँटें। 4) आप ऑर्डर के भीतर फील्ड फंक्शन को क्लॉज द्वारा उपयोग कर सकते हैं। उदाहरण के लिए

फ़ील्ड द्वारा क्रमबद्ध करें (Sort_field, 1,4,3,2)


3

मुझे नहीं लगता कि यह MySQL विशिष्ट है, लेकिन मेरे लिए ज्ञानवर्धक है:

लिखने के बजाय

WHERE (x.id > y.id) OR (x.id = y.id AND x.f2 > y.f2) 

आप बस लिख सकते हैं

WHERE (x.id, x.f2) > (y.id, y.f2)

यह वास्तव में अच्छा है लेकिन इसके लिए कुछ उपयोग के मामले क्या होंगे?
मैंगड्रैक

यह उन सभी रिकॉर्डों को खोजने के लिए उपयोगी हो सकता है जो किसी दिए गए रिकॉर्ड से बड़े हैं।
फंटियस

2

mysqlsla - आमतौर पर उपयोग किए जाने वाले धीमी क्वेरी लॉग विश्लेषण उपकरण में से एक है। आप शीर्ष 10 सबसे खराब प्रश्नों को देख सकते हैं, क्योंकि यू ने पिछली बार धीमी क्वेरी लॉग आउट किया था। यह आपको यह भी बता सकता है कि कितनी बार BAD क्वेरी को निकाल दिया गया और सर्वर पर कुल कितना समय लगा।


2

वास्तव में प्रलेखित , लेकिन बहुत कष्टप्रद: गलत तारीखों और अन्य गलत इनपुट के लिए स्वचालित रूपांतरण।

MySQL 5.0.2 से पहले, MySQL गैरकानूनी या अनुचित डेटा मानों को माफ कर रहा है और उन्हें डेटा प्रविष्टि के लिए कानूनी मूल्यों के लिए मजबूर करता है। MySQL 5.0.2 और ऊपर, कि डिफ़ॉल्ट व्यवहार रहता है, लेकिन आप खराब मूल्यों के अधिक पारंपरिक उपचार का चयन करने के लिए सर्वर SQL मोड को बदल सकते हैं जैसे कि सर्वर उन्हें अस्वीकार करता है और उस बयान को निरस्त करता है जिसमें वे होते हैं।

जैसे कि तारीखों के लिए: कभी-कभी आप "भाग्यशाली" होंगे जब MySQL आस-पास की वैध तिथियों के इनपुट को समायोजित नहीं करता है, लेकिन इसके बजाय इसे संग्रहीत करता है 0000-00-00जिसके द्वारा परिभाषा अमान्य है। हालाँकि, तब भी आप चाहते थे कि MySQL आपके लिए इस मूल्य को चुपचाप संग्रहीत करने के बजाय विफल हो जाए।



1

डिफ़ॉल्ट रूप से InnoDB एक वैश्विक टेबलस्पेस में सभी तालिकाओं को संग्रहीत करता है जो कभी भी सिकुड़ेंगे नहीं

आप उपयोग कर सकते हैं innodb_file_per_tableजो प्रत्येक टेबल को एक अलग टेबलस्पेस में डाल देगा जो टेबल या डेटाबेस को छोड़ने पर हटा दिया जाएगा।

इसके लिए आगे की योजना बनाएं क्योंकि आपको स्थान को पुनः प्राप्त करने के लिए डेटाबेस को डंप और पुनर्स्थापित करना होगा अन्यथा।

प्रति-तालिका तालिकाएँ का उपयोग करना


1

यदि आप डेटाइम कॉलम खाली स्ट्रिंग मान में सम्मिलित करते हैं "", तो MySQL मान को 00/00/0000 00:00:00 तक बनाए रखेगा। ओरेकल के विपरीत, जो शून्य मान को बचाएगा।


1

बड़े डेटासेट और DATETIME फ़ील्ड के साथ मेरे बेंचमार्क के दौरान, यह क्वेरी करना हमेशा धीमा होता है:

SELECT * FROM mytable
WHERE date(date_colum) BETWEEN '2011-01-01' AND ''2011-03-03';

इस दृष्टिकोण से आगे:

SELECT * FROM mytable
WHERE date_column BETWEEN '2011-01-01 00:00:00' AND '2011-03-03 23:59:59'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.