我想将一个表(包括其索引和触发器)从一个数据库复制到另一个数据库。这并不像我希望的那么简单。这是一个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
接下来,第一个表:
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;
:
我的问题:将复制所有缺失的项目的CREATE TABLE db2.tb1 AS SELECT * FROM db1.tb1;
简洁等同于什么?
答案 0 :(得分:2)
CREATE TABLE newTable LIKE oldTable
应包括索引和设置,但不包括数据和触发器。
之后,您需要复制数据:
INSERT INTO newTable SELECT * FROM oldTable
触发器不是表的直接部分,而是脚本管理的一部分。
您可以在information_schema.triggers
中找到触发器。在那里,您可以查询表的每个触发器集。但我强烈建议不要手动使用该表。
相反,您可以阅读其中的定义,并使用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
是一个保留字,在这里以类似名称的方式使用。
使用触发器名称,为每个触发器施放
SHOW CREATE TRIGGER triggerNameFromQueryAbove
这为您提供了可用于在新数据库中创建触发器的create语句。但要小心:可能包含数据库名称和定义者,这可能不存在于新数据库中,因此您必须手动删除该信息。
有关"触发器"的更多信息。表,阅读mysql手册(也应该适用于mariadb):https://dev.mysql.com/doc/refman/5.7/en/triggers-table.html
答案 1 :(得分:0)
我正在看这个问题,因为我有同样的问题。我有点沮丧,如果真的没有更简洁的命令来做到这一点。我想指出一个(也许是显而易见的)程序也可以工作。您可以将数据库转储到一个文件(例如“dumpdb1.sql”),如果您使用 mysqldump 进行备份,这已经很方便了。然后,您当然可以仅复制 dumpdb1.sql 中的相关文本,以创建 tb1,设置其约束和索引,并添加其触发器和数据,将此摘录放入文件“buildtb1.sql”中。最后,只需在 db2 上运行后一个文件,您就会在那里获得 tb1 的完美完整副本。
此外,我在 MariaDB 文档中看到:Tutorialspoint MariaDB Table Cloning 他们指出了 SHOW CREATE TABLE 语句在这方面的用处。它将提供一个 CREATE TABLE 语句,您可以在此过程中复制和使用。如果您不想使用它,我只是提到这是 mysqldump 方法的替代方法。当然 SHOW CREATE TABLE 不会描述触发器,因此您仍然需要执行 SHOW TRIGGERS 过程来捕获和重现这些。