如何修改乙個已存在的資料庫名稱?

時間 2021-05-06 04:48:54

1樓:愛可生

被取消的命令MySQL 之前提供了乙個 rename database db_old to db_new 的命令來直接對資料庫改名,可能由於實現的功能不完備(比如,這條命令可能是乙個超大的事務,或者是由於之前的表很多還是 MyISAM 等),後來的版本直接取消了這條命令。更改資料庫名大致上有以下幾種方案:

一、mysqldump 匯入匯出要說最簡單的方法,就是直接用 mysqldump 工具,在舊庫匯出再往新庫匯入(最原始、最慢、最容易想到)的方法:舊庫 yttdb_old 匯出(包含的物件:表、檢視、觸發器、事件、儲存過程、儲存函式)

root@debian-ytt1:/home/ytt# time mysqldump --login-path=root_ytt --set-gtid-purged=off --single-transaction --routines --events yttdb_old > /tmp/yttdb_old.sql

real 2m24.388s

user 0m5.422s

sys 0m1.120s

新庫 yttdb_new 匯入

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -D yttdb_new < /tmp/yttdb_old.sql

real 12m27.324s

user 0m3.778s

sys 0m0.947s

以上結果是在我個人筆記本的虛擬機器上測試,時間上花費了 12 分 27 秒,這裡源庫 yttdb_old 上的表個數為 2002,總共也就 826M,不到 1G,並且包含了檢視,觸發器,儲存過程,儲存函式,事件等都有。

root@debian-ytt1:/home/ytt/mysql-sandboxes/3500/sandboxdata/yttdb_old# ls -l |wc -l

2002

root@debian-ytt1:/home/ytt/mysql-sandboxes/3500/sandboxdata/yttdb_old# du -sh

826M .

二、改整庫的表名利用 MySQL 更改表名的方法來批量把舊庫的所有表依次遍歷,改名為新庫的表。這種方法比第一種要快很多倍,但是沒有第一步操作起來那麼順滑,不能一步到位。比如,要把資料庫 yttdb_old 改名為 yttdb_new,如果資料庫 yttdb_old 裡只有磁碟表,那很簡單,直接改名即可。

alter table yttdb_old.t1 to yttdb_new.t1;

或者寫個指令碼來批量改,非常簡單。但是一般舊庫里不只有磁碟表,還包含其他各種物件。這時候可以先考慮把舊庫的各種物件匯出來,完了在逐一改完表名後導進去。

匯出舊庫 yttdb_old 下除了磁碟表外的其他所有物件(儲存函式、儲存過程、觸發器、事件)

root@debian-ytt1:/home/ytt# time mysqldump --login-path=root_ytt -t -d -n --set-gtid-purged=off --triggers --routines --events yttdb_old > /tmp/yttdb_old_other_object.sql

real 1m41.901s

user 0m1.166s

sys 0m0.606s

檢視在 MySQL 裡被看作是表,因此得先查詢出檢視名字,再單獨匯出:

root@debian-ytt1:~# view_list=`mysql --login-path=root_ytt -e "SELECT table_name FROM information_schema.views WHERE table_schema = 'yttdb_old';" -s | tr '\n' ' '`

root@debian-ytt1:~# time mysqldump --login-path=root_ytt --set-gtid-purged=off --triggers=false yttdb_old $view_list > /tmp/yttdb_old_view_lists.sql

real 0m0.123s

user 0m0.007s

sys 0m0.007s

root@debian-ytt1:/home/ytt# func_lists=`mysql --login-path=root_ytt -e "SELECT concat('drop function if exists ',routine_name,';') FROM information_schema.routines WHERE routine_schema = 'yttdb_old' AND routine_type = 1 " -ss`

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -e "use yttdb_old;$func_lists"

real 0m0.048s

user 0m0.005s

sys 0m0.005s

root@debian-ytt1:/home/ytt# procedure_lists=`mysql --login-path=root_ytt -e "SELECT concat('drop procedure if exists ',routine_name,';') FROM information_schema.routines WHERE routine_schema = 'yttdb_old' AND routine_type = 2 " -ss`

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -e "use yttdb_old;$procedure_lists"

real 0m0.046s

user 0m0.006s

sys 0m0.005s

root@debian-ytt1:/home/ytt# trigger_lists=`mysql --login-path=root_ytt -e "SELECT concat('drop trigger if exists yttdb_old.',trigger_name,';') FROM information_schema.

TRIGGERS WHERE trigger_schema='yttdb_old'" -ss`

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -e "use yttdb_old;$trigger_lists"

real 0m0.050s

user 0m0.008s

sys 0m0.003s

root@debian-ytt1:/home/ytt# view_lists=`mysql --login-path=root_ytt -e "SELECT concat('drop view if exists ',table_name,';') FROM information_schema.VIEWS WHERE table_schema='yttdb_old'" -ss`

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -e "use yttdb_old;$view_lists"

real 0m0.070s

user 0m0.006s

sys 0m0.005s

root@debian-ytt1:/home/ytt# event_lists=`mysql --login-path=root_ytt -e "SELECT concat('drop event if exists ',event_name,';') FROM information_schema.EVENTS WHERE event_schema='yttdb_old'" -ss`

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -e "use yttdb_old;$event_lists"

real 0m0.054s

user 0m0.011s

sys 0m0.000s

完了後利用 rename table old_table to new_table 語句來批量更改表名到新庫:

(debian-ytt1:3500)|(yttdb_new)>set group_concat_max_len = 18446744073709551615;

Query OK, 0 rows affected (0.00 sec)

(debian-ytt1:3500)|(yttdb_new)>SELECT CONCAT('rename table ',

GROUP_CONCAT(CONCAT(' yttdb_old.',table_name,' to yttdb_new.',table_name)) )

FROM information_schema.TABLES

WHERE table_schema = 'yttdb_old' AND table_type = 1 INTO @rename_lists;

Query OK, 1 row affected (0.01 sec)

(debian-ytt1:3500)|(yttdb_new)>prepare s1 from @rename_lists;

Query OK, 0 rows affected (0.00 sec)

Statement prepared

(debian-ytt1:3500)|(yttdb_new)>execute s1;

Query OK, 0 rows affected (55.41 sec)

(debian-ytt1:3500)|(yttdb_new)>drop prepare s1;

Query OK, 0 rows affected (00.01 sec)

批量更改表名總共才花費 55.41 秒。接下來再把之前匯出來的其他物件匯入新庫 yttdb_new:

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -D yttdb_new < /tmp/yttdb_old_other_object.sql

real 0m0.222s

user 0m0.081s

sys 0m0.000s

root@debian-ytt1:/home/ytt# time mysql --login-path=root_ytt -D yttdb_new < /tmp/yttdb_old_view_lists.sql

real 0m0.158s

user 0m0.013s

sys 0m0.000s

接下來進行功能驗證,驗證表數量、觸發器、儲存過程、儲存函式、事件等數目是不是對的上。

三、歷史方案其實在 MySQL 早期還有一種方法。假設 MySQL 部署好了後,所有的 binlog 都有備份,並且二進位制日誌格式還是 statement 的話,那就可以簡單搭建一台從機,讓它慢慢追主機到新的庫名,等確切要更改舊庫的時候,再直接晉公升從機為主機即可。這裡只需要從機配置乙個引數來把舊庫指向為新庫:

replicate-rewrite-db=yttdb_old->yttdb_new不過這種侷限性很大,不具備標準化,不推薦。

總結其實針對 MySQL 本身改庫名,大致就這麼幾種方法:

如果資料量小,推薦第一種;

資料量大,則推薦第二種;

資料量巨大,那就非 MySQL 本身能解決的了。

可通過部署第三方 ETL 工具,通過解析 MySQL 二進位制日誌或其他的方式來把舊庫資料直接讀取到新庫達到改名的目的等等。

怎麼實現乙個簡單的資料庫系統?

劉浩浩 這種類似的東西,最重要的是一定要看過已經有的開源實現的原始碼,從頭到尾搞懂別人的思路。我自己寫過基於UDP的可靠協議,用go寫的,開始寫之前看了各種他人的原始碼和一些已有的實現,感覺受益匪淺,後面寫起來感覺前期的調研是很重要的。因此建議,先看懂乙個完整的實現,不需要mysql這樣的大東西,看...

c 用乙個方法讀取資料庫資料到不同Model類的例項,如何用泛型實現?

如果只是一句 SQL 泛型約束 執行 泛型類例項這樣的需求有很多方法,說來說去也就三個主要步驟 一.執行 SQL 語句,返回 DataReader 或者 DataTable,這兩個都可以使用列名訪問到資料。二.選擇不同的方式建立 Model 與資料庫表的對映關係,最簡單就是 PropertyName...

作為乙個K V資料庫,levelDB索引為什麼要使用LSM樹實現,而不採用雜湊索引?

lxyscls 參考一下CMU15 445,磁碟上的雜湊和記憶體中的雜湊實現上不太一樣,所以不是太適合做磁碟的索引,當然bitcask其實是把雜湊索引放到記憶體裡面。 讀 有序的索引功能會豐富很多,比如levelDb可以支援snapshot read,hash的話想來只能做backup了。另外Has...