将 table 从一个 MariaDB 数据库克隆到另一个数据库,包括默认值、索引和触发器?
Clone table from one MariaDB database to another, including defaults, indexes and triggers?
我想将 table 包括其索引和触发器从一个数据库复制到另一个数据库。这并不像我希望的那么简单。这里有一个minimal working example (MWE)来演示。首先,我的 MariaDB 版本:
$ mysql --version
mysql Ver 15.1 Distrib 10.0.29-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
下一个table:
CREATE DATABASE db1;
USE db1;
CREATE TABLE tb1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
word VARCHAR(50) NOT NULL);
INSERT INTO tb1 (word) VALUES ('foo');
DELETE FROM tb1 WHERE word='foo';
DELIMITER $$
CREATE TRIGGER before_word_insert BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
SET NEW.word=TRIM(NEW.word);
IF NOT (NEW.word REGEXP '^[[:alpha:]]+$') THEN
SIGNAL SQLSTATE '12345' SET MESSAGE_TEXT = 'Invalid word';
END IF;
END$$
DELIMITER ;
INSERT INTO tb1 (word) VALUES ('foo');
DESCRIBE tb1;
SHOW TRIGGERS;
SHOW INDEX FROM tb1;
最后三行给出:
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| word | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
+--------------------+--------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+--------------------+--------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| before_word_insert | INSERT | tb1 | BEGIN SET NEW.word=TRIM(NEW.word); IF NOT (NEW.word REGEXP '^[[:alpha:]]+$') THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid word'; END IF; END | BEFORE | NULL | | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci |
+--------------------+--------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
1 row in set (0.04 sec)
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tb1 | 0 | PRIMARY | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
到目前为止,还不错。现在,要将 tb1
复制到另一个数据库(在同一台服务器上):
CREATE DATABASE db2;
USE db2;
CREATE TABLE db2.tb1 AS SELECT * FROM db1.tb1;
DESCRIBE tb1;
SHOW TRIGGERS;
SHOW INDEX FROM tb1;
我曾希望这最后三行会给出与 db1
相同的输出,但它们没有:
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | 0 | |
| word | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
Empty set (0.00 sec)
Empty set (0.00 sec)
换句话说,CREATE TABLE db2.tb1 AS SELECT * FROM db1.tb1;
:
- 复制了table内容;
- 复制了列类型;
- 没有复制 "Key" 属性;
- 没有复制 "Default" 属性;
- 没有复制 "Extra" 属性;
- 没有复制触发器;和
- 没有复制索引。
我的问题: 什么是 CREATE TABLE db2.tb1 AS SELECT * FROM db1.tb1;
的简明等效项, 会 复制所有丢失的项目?
CREATE TABLE newTable LIKE oldTable
应该包括索引和设置,但不包括数据和触发器。
之后需要复制数据:
INSERT INTO newTable SELECT * FROM oldTable
触发器不直接是 table 的一部分,而是脚本管理的一部分。
您可以在 information_schema.triggers
中找到触发器。您可以在那里查询为您的 table 设置的每个触发器。但我强烈建议不要手动table。
相反,您可以阅读那里的定义并使用 SHOW CREATE TRIGGER
和 CREATE TRIGGER
创建一个新触发器。这涉及动态 sql 或能够操纵 sql 的客户端(这应该适用于每个客户端)。
如果有一个客户端连接到源数据库和目标数据库,你可以这样做:
SELECT `TRIGGER_NAME` FROM information_schema.triggers WHERE `TRIGGER_SCHEMA` = database() AND `EVENT_OBJECT_TABLE` = oldTableName
如您在评论中所述,您也可以使用
SHOW TRIGGERS WHERE `Table` = "oldTable"
而不是读取触发器 table。作为旁注,Table
周围的这些反引号很重要,因为 Table
是一个保留字,在这里以类似于列名的方式使用。
使用触发器名称,对于您施放的每个触发器
SHOW CREATE TRIGGER triggerNameFromQueryAbove
这为您提供了可用于在新数据库中创建触发器的创建语句。但要注意:可能包含的数据库名称和定义者,新数据库中可能不存在,因此您必须手动删除这些信息。
有关 "triggers" table 的更多信息,请阅读 mysql 手册(也适用于 mariadb):https://dev.mysql.com/doc/refman/5.7/en/triggers-table.html
我正在看这个问题,因为我也有同样的问题。我有点沮丧,如果真的没有更简洁的命令来做到这一点。我想指出一个(可能是显而易见的)程序也可以工作。您可以将数据库转储到一个文件(例如,“dumpdb1.sql”),如果您使用 mysqldump 进行备份,这已经很方便了。然后,您当然可以从创建 tb1 的 dumpdb1.sql 中复制相关文本,设置其约束和索引,并添加其触发器和数据,将此摘录放入文件“buildtb1.sql” .最后,只需 运行 db2 上的后一个文件,您就应该在那里获得完美的 完整 tb1 副本。
此外,我在 MariaDB 文档中看到:Tutorialspoint MariaDB Table Cloning 他们指出了 SHOW CREATE TABLE 语句在这方面的有用性。它将给出一个 CREATE TABLE 语句,您可以在此过程中复制和使用。如果您不想使用它,我只是提到它作为 mysqldump 方法的替代方法。当然 SHOW CREATE TABLE 不会描述触发器,因此您仍然需要执行 SHOW TRIGGERS 过程来捕获和重现这些触发器。
我想将 table 包括其索引和触发器从一个数据库复制到另一个数据库。这并不像我希望的那么简单。这里有一个minimal working example (MWE)来演示。首先,我的 MariaDB 版本:
$ mysql --version
mysql Ver 15.1 Distrib 10.0.29-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
下一个table:
CREATE DATABASE db1;
USE db1;
CREATE TABLE tb1 (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
word VARCHAR(50) NOT NULL);
INSERT INTO tb1 (word) VALUES ('foo');
DELETE FROM tb1 WHERE word='foo';
DELIMITER $$
CREATE TRIGGER before_word_insert BEFORE INSERT ON tb1 FOR EACH ROW
BEGIN
SET NEW.word=TRIM(NEW.word);
IF NOT (NEW.word REGEXP '^[[:alpha:]]+$') THEN
SIGNAL SQLSTATE '12345' SET MESSAGE_TEXT = 'Invalid word';
END IF;
END$$
DELIMITER ;
INSERT INTO tb1 (word) VALUES ('foo');
DESCRIBE tb1;
SHOW TRIGGERS;
SHOW INDEX FROM tb1;
最后三行给出:
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| word | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)
+--------------------+--------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| Trigger | Event | Table | Statement | Timing | Created | sql_mode | Definer | character_set_client | collation_connection | Database Collation |
+--------------------+--------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
| before_word_insert | INSERT | tb1 | BEGIN SET NEW.word=TRIM(NEW.word); IF NOT (NEW.word REGEXP '^[[:alpha:]]+$') THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Invalid word'; END IF; END | BEFORE | NULL | | root@localhost | utf8 | utf8_general_ci | latin1_swedish_ci |
+--------------------+--------+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------+--------+---------+----------+----------------+----------------------+----------------------+--------------------+
1 row in set (0.04 sec)
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| tb1 | 0 | PRIMARY | 1 | id | A | 3 | NULL | NULL | | BTREE | | |
+-------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
1 row in set (0.00 sec)
到目前为止,还不错。现在,要将 tb1
复制到另一个数据库(在同一台服务器上):
CREATE DATABASE db2;
USE db2;
CREATE TABLE db2.tb1 AS SELECT * FROM db1.tb1;
DESCRIBE tb1;
SHOW TRIGGERS;
SHOW INDEX FROM tb1;
我曾希望这最后三行会给出与 db1
相同的输出,但它们没有:
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | | 0 | |
| word | varchar(50) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)
Empty set (0.00 sec)
Empty set (0.00 sec)
换句话说,CREATE TABLE db2.tb1 AS SELECT * FROM db1.tb1;
:
- 复制了table内容;
- 复制了列类型;
- 没有复制 "Key" 属性;
- 没有复制 "Default" 属性;
- 没有复制 "Extra" 属性;
- 没有复制触发器;和
- 没有复制索引。
我的问题: 什么是 CREATE TABLE db2.tb1 AS SELECT * FROM db1.tb1;
的简明等效项, 会 复制所有丢失的项目?
CREATE TABLE newTable LIKE oldTable
应该包括索引和设置,但不包括数据和触发器。
之后需要复制数据:
INSERT INTO newTable SELECT * FROM oldTable
触发器不直接是 table 的一部分,而是脚本管理的一部分。
您可以在 information_schema.triggers
中找到触发器。您可以在那里查询为您的 table 设置的每个触发器。但我强烈建议不要手动table。
相反,您可以阅读那里的定义并使用 SHOW CREATE TRIGGER
和 CREATE TRIGGER
创建一个新触发器。这涉及动态 sql 或能够操纵 sql 的客户端(这应该适用于每个客户端)。
如果有一个客户端连接到源数据库和目标数据库,你可以这样做:
SELECT `TRIGGER_NAME` FROM information_schema.triggers WHERE `TRIGGER_SCHEMA` = database() AND `EVENT_OBJECT_TABLE` = oldTableName
如您在评论中所述,您也可以使用
SHOW TRIGGERS WHERE `Table` = "oldTable"
而不是读取触发器 table。作为旁注,Table
周围的这些反引号很重要,因为 Table
是一个保留字,在这里以类似于列名的方式使用。
使用触发器名称,对于您施放的每个触发器
SHOW CREATE TRIGGER triggerNameFromQueryAbove
这为您提供了可用于在新数据库中创建触发器的创建语句。但要注意:可能包含的数据库名称和定义者,新数据库中可能不存在,因此您必须手动删除这些信息。
有关 "triggers" table 的更多信息,请阅读 mysql 手册(也适用于 mariadb):https://dev.mysql.com/doc/refman/5.7/en/triggers-table.html
我正在看这个问题,因为我也有同样的问题。我有点沮丧,如果真的没有更简洁的命令来做到这一点。我想指出一个(可能是显而易见的)程序也可以工作。您可以将数据库转储到一个文件(例如,“dumpdb1.sql”),如果您使用 mysqldump 进行备份,这已经很方便了。然后,您当然可以从创建 tb1 的 dumpdb1.sql 中复制相关文本,设置其约束和索引,并添加其触发器和数据,将此摘录放入文件“buildtb1.sql” .最后,只需 运行 db2 上的后一个文件,您就应该在那里获得完美的 完整 tb1 副本。
此外,我在 MariaDB 文档中看到:Tutorialspoint MariaDB Table Cloning 他们指出了 SHOW CREATE TABLE 语句在这方面的有用性。它将给出一个 CREATE TABLE 语句,您可以在此过程中复制和使用。如果您不想使用它,我只是提到它作为 mysqldump 方法的替代方法。当然 SHOW CREATE TABLE 不会描述触发器,因此您仍然需要执行 SHOW TRIGGERS 过程来捕获和重现这些触发器。