如何在 MySQL 中为数据库起别名?
Posted
技术标签:
【中文标题】如何在 MySQL 中为数据库起别名?【英文标题】:How do I alias a database in MySQL? 【发布时间】:2010-11-21 03:25:58 【问题描述】:我正在寻找一种在 mysql 中为数据库设置别名的方法。原因是能够在不关闭系统的情况下重命名实时生产数据库。我想我可以将数据库别名为新名称,在闲暇时更改和部署连接到它的代码,并最终删除旧别名。
如果有更好的方法可以做到这一点,请告诉我。
【问题讨论】:
如果 MySQL 没有内置的东西,DBI 的代理功能可能有用。 @jrockway 得知我正在支持 php 应用程序时,您会感到震惊。 【参考方案1】:使用下面引用的代码创建同义词。
跨存储引擎(例如:InnoDB、MyISAM 等)执行此操作的最简单方法是对数据库的所有访问使用“同义词”。
这些链接将向您展示完成此操作所需的存储过程。
注意:您应该删除“sys.”来自“create_synonym_db.sql”中的“sys.quote_identifier”(应该只是“quote_identifier”)。
代码:
https://github.com/mysql/mysql-sys/blob/master/procedures/create_synonym_db.sql https://github.com/mysql/mysql-sys/blob/master/functions/quote_identifier.sql使用方法:
这将为“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) 按同义词正常使用数据库:
“FAKE_DB_NAME”引用数据库的所有 SQL 代码(3) 使用您选择的任何方法创建临时/备份/替换数据库。
(4) 将所有应用层 SQL 代码切换到 Temp DB
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”中(从应用程序层)进行维护。
【讨论】:
【参考方案2】:https://dev.mysql.com/doc/refman/5.7/en/symbolic-links-to-databases.html 说
MySQL 不支持将一个目录链接到多个数据库。
您可以使用符号链接将数据库目录链接到其他位置,例如数据目录之外。
$ cd /var/lib/mysql
$ ln -s /other/dir/mydatabase .
但您不能使用符号链接将一个数据库目录设为另一个 MySQL 数据库的“别名”:
$ cd /var/lib/mysql
$ ln -s `pwd`/mydatabase1 mydatabase2 # WRONG
原因是 InnoDB 将数据库名称和其他元数据保留在自己的数据字典中,存储在表空间文件中。如果你把它弄混了,你就得不到你想要的。
MySQL 没有任何用于为数据库起别名的 DDL 语法。
【讨论】:
我从没想过!你(好吧,不是你,Bill),忘记数据库只是文件。 谢谢!我考虑过,但不知道它是否安全。 我无权访问亚马逊数据库服务器的文件系统 @BerryTsakala,那么您不能为数据库设置别名。当您使用 Amazon RDS 时,您会牺牲一些灵活性。 这看起来很可怕。【参考方案3】:在 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
【讨论】:
【参考方案4】:INNODB 不适用于文件系统符号链接。
【讨论】:
我还没有尝试过确认,但如果您使用 InnoDB 和 file-per-table 选项,而不是共享表空间,它可能会起作用。 如果链接在 datadir 即/var/lib/mysql
中,它可以正常工作。不幸的是,您还得到了长名称数据库的损坏版本。
如果你设置 innodb_file_per_table 这不会使数据库目录更可移动。您仍然无法将其移出 datadir。以上是关于如何在 MySQL 中为数据库起别名?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中为类名起别名,而不必向使用该类的每个文件添加一行代码?
如何在 Laravel Eloquent 查询(或使用查询生成器)中为表起别名?