如何在MySQL中为数据库设置别名?

20
我正在寻找在MySQL中创建数据库别名的方法。原因是希望能够重命名一个正在运行、生产环境中的数据库而无需停机。我考虑将数据库创建一个新名字的别名,随后可以慢慢修改和部署与之连接的代码,最终再删除旧的别名。
如果有更好的方法,请告知。

如果MySQL没有内置的功能,DBI的代理功能可能会有用。 - jrockway
1
@jrockway 你会惊讶地发现我正在支持一个 PHP 应用程序。 - Schwern
4个回答

10
请参考下面的代码来创建同义词。
最简单的方法是使用一个“同义词”来访问数据库,以跨存储引擎(如InnoDB,MyISAM等)的方式进行操作。
以下链接将展示您需要完成此操作所需的存储过程。
注意:在“create_synonym_db.sql”中,应该从“sys.quote_identifier”中删除“sys。”(只需为“quote_identifier”)。
代码: 使用方法:
这将为“CURRENT_DB”创建一个匹配的访问模式,使得通过引用“FAKE-DB_NAME”可以实现所有标准SQL功能。
CALL create_synonym_db('CURRENT_DB', 'FAKE_DB_NAME');

删除同义词:

这将删除同义词,但不会删除原始数据库(在Maria 10.10.0系列上测试通过)。

DROP DATABASE FAKE_DB_NAME;

为了达成您的需求,您需要让所有应用程序层使用“FAKE_DB_NAME”进行通信,并在需要进行所讨论的维护形式时,移除当前的同义词并替换为指向其他数据库的同义词。
因此,一旦为正确的维护账户(无论您用于此类维护的MySQL账户是什么)加载了这些存储过程,您需要执行以下操作:
(1) 创建一个同义词:
CALL create_synonym_db('NormalDB', 'FAKE_DB_NAME');

(2) 使用同义词将数据库视为正常:

  • 所有引用数据库的 SQL 代码都使用“FAKE_DB_NAME”

(3) 使用您选择的任何方法创建临时/备份/替换数据库。

(4) 将应用程序层 SQL 代码切换到临时数据库

DROP DATABASE FAKE_DB_NAME;
CALL create_synonym_db('TempDB', 'FAKE_DB_NAME');

(5) 在“NormalDB”上执行您计划的任何维护操作。

(6) 将所有应用程序层SQL代码切换到Temp DB。

这两个事务应该几乎是瞬间完成的。

DROP DATABASE FAKE_DB_NAME;
CALL create_synonym_db('NormalDB', 'FAKE_DB_NAME');

这将使您能够无缝地切换任何数据库,而无需更改应用程序层的代码。

重要提示:请注意,在您“切换”到“TempDB”时,对其进行的任何更改都不会在“NormalDB”中体现,因为您已经将其从应用程序层次中“下线”以进行维护。


9

https://dev.mysql.com/doc/refman/5.7/en/symbolic-links-to-databases.html 上写道:

MySQL不支持将一个目录链接到多个数据库。

您可以使用符号链接将数据库目录链接到其他位置,例如datadir之外的位置。

$ cd /var/lib/mysql
$ ln -s /other/dir/mydatabase .

但是你不能使用符号链接来将一个数据库目录作为另一个MySQL数据库的“别名”:

$ cd /var/lib/mysql
$ ln -s `pwd`/mydatabase1 mydatabase2  # WRONG

原因在于InnoDB将数据库名称和其他元数据保存在其自己的数据字典中,存储在表空间文件中。如果混淆,您将无法得到想要的结果。

MySQL没有任何DDL语法来为数据库设置别名。


我从未想过那个!你(好吧,不是,比尔),忘记了数据库只是文件。 - nickf
谢谢!我考虑过,但不知道是否安全。 - Schwern
我无法访问亚马逊的数据库服务器文件系统。 - Berry Tsakala
@BerryTsakala,你不能给数据库起别名。当你使用Amazon RDS时,你会牺牲一些灵活性。 - Bill Karwin
那看起来很可怕。 - jgmjgm

2

使用文件系统符号链接时,INNODB 将无法工作。


我没有尝试过确认,但如果您使用InnoDB与文件表选项而不是共享表空间,则可能会起作用。 - Bill Karwin
如果链接在 datadir/var/lib/mysql 中,它可以正常工作。不幸的是,您也会得到一个损坏的长命名数据库版本。 - TimP
如果您设置了innodb_file_per_table,这并不会使数据库目录更易移动。您仍然无法将其移动到datadir之外。 - TimP

0
在Unix上,符号链接数据库的方法是首先在某个有空闲空间的磁盘上创建一个目录,然后从MySQL数据目录创建一个软链接指向该目录。
shell> mkdir /dr1/databases/test
shell> ln -s /dr1/databases/test /path/to/datadir

MySQL不支持将一个目录链接到多个数据库。用符号链接替换数据库目录可以正常工作,只要您不在数据库之间创建符号链接。假设您在MySQL数据目录下有一个名为db1的数据库,然后创建一个指向db1的符号链接db2:

shell> cd /path/to/datadir
shell> ln -s db1 db2

结果是,在数据库db1中的任何表tbl_a,也会在数据库db2中出现一个表tbl_a。如果一个客户端更新了db1.tbl_a,而另一个客户端更新了db2.tbl_a,则可能会出现问题。

要确定数据目录的位置,请使用以下语句:

SHOW VARIABLES LIKE 'datadir';

来源: http://dev.mysql.com/doc/refman/5.1/en/symbolic-links.html

Ubuntu/Debian 示例

警告:不适用于 MyISAM 表格

1) 确定您的数据目录位置:

echo "SHOW VARIABLES LIKE 'datadir';" | mysql -u root -p

2) 前往您的数据目录并停止 mysql 服务:

sudo su
service mysql stop
cd path/to/datadir

3) 创建软链接:

ln -s current_db db_alias

4) 修复权限:

chown -R mysql:mysql db_alias

5) 启动 mysql

service mysql start

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接