खाली टेबल कैसे छोड़ें


11

क्या मेरे विशाल डेटाबेस (mysql) से सभी खाली तालिकाओं को गिराना संभव है?

मैं उन सभी खाली तालिकाओं को स्वचालित रूप से हटाने के लिए एक sql कमांड की तलाश कर रहा हूं।

वर्तमान में, मेरे डेटासेट में 305 टेबल हैं, और उनमें से लगभग 30% पुरानी खाली टेबल हैं, जिनका उपयोग मेरे नए एप्लिकेशन में नहीं किया जाएगा।

केवल स्पष्ट करने हेतु; सभी तालिकाएँ प्रकार = MyISAM की हैं


1
क्या सभी टेबल MyISAM, InnoDB, या दोनों का मिश्रण हैं ???
रोलैंडमाइसीडीडीबीए

वे सभी MyISAM
Qualbeen

जवाबों:


11

विचार शायद खाली तालिकाओं का उपयोग करने के लिए देखना होगा INFORMATION_SCHEMA.TABLES

SELECT * 
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_ROWS =  '0'
AND TABLE_SCHEMA = 'my_database_only'

तब आप SQL क्वेरी के साथ उत्पादन करने में सक्षम हो सकते हैं

SELECT CONCAT('DROP TABLE ', GROUP_CONCAT(table_name), ';') AS query
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_ROWS = '0'
AND TABLE_SCHEMA = 'my_database_only';

जल्दी और थोड़ा गंदा, लेकिन वास्तव में काम करना चाहिए।


3
... और फिर आपके पास एक टूटा हुआ डेटाबेस सर्वर है क्योंकि आपके पास "शायद" कुछ mysql सिस्टम तालिकाओं को हटा दिया है ... इस तथ्य के अलावा कि आपका CONCAT स्कीमा संदर्भ के बिना एक तालिका सूची बनाता है।
क्रिस्टियन पोर्टा

1
आपके पास अपनी तालिकाओं में डेटाबेस प्रतिबंधों को स्मार्ट तरीके से जोड़ने के लिए "सही" भी है, मुझे लगा कि यह स्पष्ट था।
टॉम डेसप

3
उत्तर के लिए कुछ भी नहीं लेना चाहिए क्योंकि उत्तर संभावित रूप से उपयोगकर्ता के लिए खतरनाक है ... यह सब है
क्रिश्चियन पोर्टा

2
एक एकल ड्रॉप टेबल कमांड की स्थापना के लिए +1।
रोलैंडम्यूसीडीडीबीए

1
@ एसी: ओके, मैं इसे प्राप्त करता हूं, मेरी भयानक गलती है, इसीलिए मैंने इसका उत्तर संपादित किया। वैसे, मैं थोड़ा हैरान हूं कि एक SQL क्वेरी वास्तव में एक MySQL सिस्टम आंतरिक तालिका को छोड़ सकती है। मेरे दृष्टिकोण से, यह पूरी तरह से टूट गया है।
टॉम डेसप

8

चूंकि सभी टेबल MyISAM हैं, इसलिए इससे मेरा उत्तर व्यक्त करने में आसानी होती है।

सबसे पहले, आपको उन सूचनाओं के लिए INFORMATION_SCHEMA को क्वेरी करना होगा जिसमें शून्य पंक्तियाँ हैं:

SELECT table_schema,table_name FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema');

अगला, खाली टेबल छोड़ने के लिए क्वेरी तैयार करें:

SELECT CONCAT('DROP TABLE ',table_schema,'.',table_name,';') DropTableCommand
FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema');

अब, कमांड्स को बाहरी SQL टेक्स्ट फाइल में डंप करें।

SQL="SELECT CONCAT('DROP TABLE ',table_schema,'.',table_name,';') DropTableCommand"
SQL="${SQL} FROM information_schema.tables WHERE table_rows = 0 AND table_schema"
SQL="${SQL} NOT IN ('information_schema','mysql','performance_schema')"
mysql -uroot -p -ANe"${SQL}" > DropTables.sql

निम्नलिखित में से किसी एक के साथ सामग्री को देखें

  • less DropTables.sql
  • cat DropTables.sql

यदि आप इसकी सामग्री से संतुष्ट हैं, तो स्क्रिप्ट चलाएँ:

mysql -uroot -p < DropTables.sql

या mysql में लॉगिन करें और इसे इस तरह से चलाएं:

mysql> source DropTables.sql

कोशिश करो !!!

गुफा : यह तकनीक केवल MyISAM तालिका के साथ काम करती है क्योंकि MyISAM तालिका की पंक्ति गणना भौतिक रूप .MYDसे तालिकाओं में संग्रहीत होती है । INFORMATION_SCHEMA.TABLES मेटाडेटा तालिका हमेशा इसे पढ़ रही है और अपडेट कर रही है। INNODB के साथ इस कोशिश मत करो !!!

अद्यतन 2014-02-05 11:46 ईएसटी

एक कारण है जिसे मैंने बाहर रखा है ('information_schema','mysql','performance_schema')

mysqlस्कीमा उस में खाली टेबल है। कुछ MyISAM, कुछ InnoDB, कुछ CSV

उदाहरण के लिए, यहां MySQL 5.6.15 के लिए mysql स्कीमा में मेरे डेस्कटॉप पर मेरे टेबल हैं

mysql> select table_name,engine,table_rows
    -> from information_schema.tables
    -> where table_schema='mysql';
+---------------------------+--------+------------+
| table_name                | engine | table_rows |
+---------------------------+--------+------------+
| columns_priv              | MyISAM |          0 |
| db                        | MyISAM |          2 |
| event                     | MyISAM |          0 |
| func                      | MyISAM |          0 |
| general_log               | CSV    |          2 |
| help_category             | MyISAM |         40 |
| help_keyword              | MyISAM |        485 |
| help_relation             | MyISAM |       1090 |
| help_topic                | MyISAM |        534 |
| innodb_index_stats        | InnoDB |          0 |
| innodb_table_stats        | InnoDB |          0 |
| ndb_binlog_index          | MyISAM |          0 |
| plugin                    | MyISAM |          0 |
| proc                      | MyISAM |          0 |
| procs_priv                | MyISAM |          0 |
| proxies_priv              | MyISAM |          1 |
| servers                   | MyISAM |          0 |
| slave_master_info         | InnoDB |          0 |
| slave_relay_log_info      | InnoDB |          0 |
| slave_worker_info         | InnoDB |          0 |
| slow_log                  | CSV    |          2 |
| tables_priv               | MyISAM |          0 |
| time_zone                 | MyISAM |          0 |
| time_zone_leap_second     | MyISAM |          0 |
| time_zone_name            | MyISAM |          0 |
| time_zone_transition      | MyISAM |          0 |
| time_zone_transition_type | MyISAM |          0 |
| user                      | MyISAM |          6 |
+---------------------------+--------+------------+
28 rows in set (0.01 sec)

mysql>

उन तालिकाओं में से कुछ (जैसे गायब करना हो तो columns_priv, proc_priv, tables_priv, आदि), अनुदान तंत्र ठीक से काम नहीं कर सकते हैं या mysqld कारण शुरू करने के लिए नहीं कर सकते हैं। आप यह नहीं चाहते हैं कि mysql.proc को मिटा दें क्योंकि यह संग्रहीत कार्यविधियों का भौतिक घर है। अन्य तंत्र काम नहीं कर सकते हैं या तो आपको उनका उपयोग करना चाहिए, जैसे कि क्रैसफेरा प्रतिकृति जैसे कि माईस्क स्कीमा के अंदर इनोबीडी तालिकाओं का उपयोग करना, या यदि आप समयक्षेत्र की जानकारी सम्मिलित करना चाहते हैं।

अद्यतन 2014-02-05 12:36 ईएसटी

मैं एक विशिष्ट कारण के लिए उनके जवाब के लिए टॉम डेस्प की सराहना करना चाहूंगा : उनका वाक्यविन्यास बाहरी स्क्रिप्ट का उपयोग किए बिना ड्रॉप कर सकता है । उनके विचार का उपयोग करते हुए, मैं एक उपयोगकर्ता द्वारा परिभाषित चर में DROP टेबल कमांड को कैप्चर करता हूं।

SELECT CONCAT('DROP TABLE ',GROUP_CONCAT(DBTB),';')
INTO @DropCommand
FROM (SELECT CONCAT(table_schema,'.',table_name) DBTB
FROM information_schema.tables
WHERE table_rows = 0 AND table_schema NOT IN
('information_schema','mysql','performance_schema')) A;
SELECT @DropCommand;

यदि आउटपुट SELECT @DropCommand;सही है, तो कमांड को इस तरह निष्पादित करें:

PREPARE s FROM @DropCommand;
EXECUTE s;
DEALLOCATE PREPARE s;

यह दो चीजों को समाप्त करता है:

  • बाहरी SQL पाठ फ़ाइल की आवश्यकता
  • प्रत्येक तालिका के लिए एक अलग DROP टेबल कमांड चला रहा है

1
एक लंबी और अच्छी व्याख्या के लिए धन्यवाद! डेटाबेस में तालिकाएँ लौटने के लिए +1। इस तरह से कई डेटासेट को साफ करना आसान है। दूसरी ओर; देखभाल के साथ उपयोग करें। मैं आपकी क्वेरी को "..AND table_schema = 'my_database_name'" के विरुद्ध केवल एक डेटाबेस के साथ काम करने के लिए चलाता हूं (जैसा कि टॉम डेस्प ने एक अन्य उत्तर में सुझाया है)
Qualbeen
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.