MySQL數據庫導入、導出、複製表、重命名錶

前言

提前說明這是一篇小白總結,高手勿噴請繞行,寫這篇總結的原因是發覺自己有時候確實眼高手低了,大道至簡,花了很多時間去看索引、緩存、主從等等,等到出現實際問題的時候卻發現自己磨磨蹭蹭寫出的SQL語句居然有語法錯誤,看來還得穩紮穩打從基礎入手,因爲實際工作的用到的SQL並不多,現在把常用的幾條總結一下,即使下次不能立馬寫出來,也能在這篇文章中的快速找到想要的。

正如標題中的提到的這些,數據庫的導入和導出在緊急處理線上數據時很常用,而複製表基本上也是爲了不影響原數據的情況下進行問題排查,重命名錶是爲了導入多份備份數據時原數據不被覆蓋,比如想對比兩天的A表數據,可以先把第一天的數據導入,然後將A表名修改成Aold,接着直接再導入第二天的數據庫數據,這樣就可以將數據庫中表Aold和A進行對比了,可以避免兩個數據庫中的同一個表進行對比時寫很長的SQL。

測試環境

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 5.7.28-log MySQL Community Server (GPL)
Copyright © 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective owners.
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement.

測試過程

爲了說明實現這些要求的具體SQL,我們先建立一個測試數據庫,然後創建測試表格,插入測試數據,最後在這個數據庫上依次實現這些要求。

創建測試數據

創建測試數據庫和表格

mysql> create database dbtest;
Query OK, 1 row affected (0.00 sec)

mysql> use dbtest
Database changed

mysql> create table a(id int, num int);
Query OK, 0 rows affected (0.02 sec)

mysql> create table b(id int, name varchar(32));
Query OK, 0 rows affected (0.01 sec)

mysql> show tables;
+--------------+
| Tables_in_zz |
+--------------+
| a            |
| b            |
+--------------+
2 rows in set (0.00 sec)

插入測試數據

mysql> insert into a values(1, 100);
Query OK, 1 row affected (0.02 sec)

mysql> insert into a values(2, 200);
Query OK, 1 row affected (0.01 sec)

mysql> select * from a;
+------+------+
| id   | num  |
+------+------+
|    1 |  100 |
|    2 |  200 |
+------+------+
2 rows in set (0.01 sec)

mysql> insert into b values(1, 'albert');
Query OK, 1 row affected (0.01 sec)

mysql> insert into b values(2, 'tom');
Query OK, 1 row affected (0.01 sec)

mysql> select * from b;
+------+--------+
| id   | name   |
+------+--------+
|    1 | albert |
|    2 | tom    |
+------+--------+
2 rows in set (0.00 sec)

數據庫導出

數據庫導出時使用的最基礎的工具叫mysqldump,這是單獨的工具不是mysql命令,剛學MySQL的時候居然在MySQL的命令行中使用mysqldump,現在只能當笑話看了。

導出指定數據庫中所有表結構和數據

在系統的命令行工具下輸入以下命令,敲入回車輸入密碼,再回車就可以將數據庫dbtest的結構和數據導出到dbtest.sql文件中:

>mysqldump -uroot -h192.168.1.101 -p dbtest > dbtest.sql

打開dbtest.sql文件,顯示如下:文件內容比較長,裏面包含了數據庫的表結構和其中的數據信息:

-- MySQL dump 10.13  Distrib 5.7.21, for Win64 (x86_64)
--
-- Host: localhost    Database: dbtest
-- ------------------------------------------------------
-- Server version   5.7.21-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `a`
--

DROP TABLE IF EXISTS `a`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `a` (
  `id` int(11) DEFAULT NULL,
  `num` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `a`
--

LOCK TABLES `a` WRITE;
/*!40000 ALTER TABLE `a` DISABLE KEYS */;
INSERT INTO `a` VALUES (1,100),(2,200);
/*!40000 ALTER TABLE `a` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `b`
--

DROP TABLE IF EXISTS `b`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `b` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `b`
--

LOCK TABLES `b` WRITE;
/*!40000 ALTER TABLE `b` DISABLE KEYS */;
INSERT INTO `b` VALUES (1,'albert'),(2,'tom');
/*!40000 ALTER TABLE `b` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2019-11-30 11:32:23

只導出指定數據庫中所有表的結構

只導出表結構的方法和上面是一樣的,只是加上 -d 選項就可以了,運行下面命令就可以將dbtest數據庫中的所有表結構導出到 dbteststructure.sql 中,因爲和上面類似,文件中的內容就不貼了,只比 dbtest.sql 文件少了插入數據的內容:

>mysqldump -uroot -h192.168.1.101 -p -d dbtest > dbteststructure.sql

只導出指定數據庫中的一個表

只導出數據庫中指定表,可以是一個也可以是多個,在數據庫名字後面跟表的名字就可以了,比如導出表a:

>mysqldump -uroot -h192.168.1.101 -p dbtest a > dbtest_a.sql

導出多個數據庫數據

出多個數據庫數據需要加上 --databases 選項,然後在後面依次跟上數據庫名字就行:

>mysqldump -uroot -h192.168.1.101 -p --databases dbtest dbtest2 > db_more.sql

導出所有數據庫數據

導出所有的數據庫時不需要加數據庫的名字,加上 --all-databases 選項就可以了

>mysqldump -uroot -h192.168.1.101 -p --all-databases > db_all.sql

數據庫導入

數據庫的導入比較簡單,實際上就是把sql文件在MySQL中執行一下,可以使用以下兩種方式:

系統命令行導入

一般需要指定導入的數據庫dbtest和sql文件的路徑,在Linux上舉例:

>mysql -uroot -h192.168.1.101 -p dbtest < /home/albert/dbtest.sql --default-character-set=utf8 

在Windows上舉例,主要是路徑需要注意,Windows上使用正斜槓/和反斜槓\都可以,默認是反斜槓,如果路徑中包含空格可以用雙引號將整個路徑包起來:

>mysql -uroot -h192.168.1.101 -p dbtest < D:\albert\dbtest.sql --default-character-set=utf8

注意--default-character-set=utf8是指定默認的字符集,主要是防止導入時出現編碼錯誤,之前總結過,在此複習一下。

MySQL命令行導入

首先連接MySQL服務器進行登陸:

>mysql -uroot -h192.168.1.101 -p --default-character-set=utf8

輸入密碼登陸後再使用source命令直接導入sql文件就可以:

mysql> source D:\albert\dbtest.sql

數據表複製

數據表的複製可以分爲結構複製和完全複製,其中完全複製時可以先複製結構,再將數據複製到新表中:

只複製表結構

  • 使用LIKE語句,只不過5.0版本之後才支持,之前的版本無法使用
CREATE TABLE new_table LIKE old_table;
mysql> select * from a;
+------+------+
| id   | num  |
+------+------+
|    1 |  100 |
|    2 |  200 |
+------+------+
2 rows in set (0.01 sec)

mysql> create table a2 like a;
Query OK, 0 rows affected (0.04 sec)

mysql> desc a2;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
| num   | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.02 sec)

mysql> select * from a2;
Empty set (0.00 sec)
  • 使用 SELECT 語句加不成立的條件實現
CREATE TABLE new_table SELECT * FROM old_table WHERE FALSE;
mysql> create table a3 select * from a where false;
Query OK, 0 rows affected (0.07 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc a3;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
| num   | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql> select * from a3;
Empty set (0.01 sec)

複製表結構和數據

  • 可以先按照上面的語句複製結構,然後再講數據複製過去:
CREATE TABLE new_table SELECT * FROM old_table WHERE FALSE;
INSERT INTO new_table SELECT * FROM old_table;
mysql> insert into a2 select * from a;
Query OK, 2 rows affected (0.07 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from a2;
+------+------+
| id   | num  |
+------+------+
|    1 |  100 |
|    2 |  200 |
+------+------+
2 rows in set (0.00 sec)
  • 直接將結構和數據全部複製
CREATE TABLE new_table SELECT * FROM old_table;
mysql> create table a4 select * from a;
Query OK, 2 rows affected (0.06 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> desc a4;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
| num   | int(11) | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.01 sec)

mysql> select * from a4;
+------+------+
| id   | num  |
+------+------+
|    1 |  100 |
|    2 |  200 |
+------+------+
2 rows in set (0.00 sec)

數據表重命名

使用 ALTER 命令實現

ALTER TABLE old_table RENAME [TO|AS] new_table;

這個語句中的TOAS是可選的,加不加都行,也可以選擇其中一個,效果是一樣的,測試如下:

mysql> show tables;
+------------------+
| Tables_in_dbtest |
+------------------+
| a                |
| b                |
+------------------+
5 rows in set (0.02 sec)

mysql> alter table b rename c;
Query OK, 0 rows affected (0.04 sec)

mysql> show tables;
+------------------+
| Tables_in_dbtest |
+------------------+
| a                |
| c                |
+------------------+
5 rows in set (0.00 sec)

mysql> alter table c rename to d;
Query OK, 0 rows affected (0.02 sec)

mysql> show tables;
+------------------+
| Tables_in_dbtest |
+------------------+
| a                |
| d                |
+------------------+
5 rows in set (0.00 sec)

mysql> alter table d rename as e;
Query OK, 0 rows affected (0.02 sec)

mysql> show tables;
+------------------+
| Tables_in_dbtest |
+------------------+
| a                |
| e                |
+------------------+
5 rows in set (0.00 sec)

使用RENAME命令

RENAME TABLE old_table TO new_table;

這個語句中TO就不能省略了,否則會報語法錯誤,測試如下:

mysql> show tables
    -> ;
+------------------+
| Tables_in_dbtest |
+------------------+
| a                |
| e                |
+------------------+
5 rows in set (0.00 sec)

mysql> rename table e to f;
Query OK, 0 rows affected (0.11 sec)

mysql> show tables;
+------------------+
| Tables_in_dbtest |
+------------------+
| a                |
| f                |
+------------------+
5 rows in set (0.01 sec)

總結

  1. 數據庫的導出、導入、數據表的複製、重命名都是MySQL操作的基礎,需要熟練掌握
  2. 數據庫導出:mysqldump -uroot -h192.168.1.101 -p dbtest > dbtest.sql
  3. 數據庫導入:mysql -uroot -h192.168.1.101 -p dbtest < /tmp/dbtest.sql --default-character-set=utf8
  4. 數據表複製:CREATE TABLE new_table SELECT * FROM old_table;
  5. 表格重命名:RENAME TABLE old_table TO new_table;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章