如何在MySQL中创建表别名

36

我正在将一个有链接到MSSQL服务器的MS Access应用程序迁移到MySQL。

为了解决一些MSAccess表命名问题,我正在寻求一种方法来添加一个MySQL表别名,它将指向MySQL数据库中现有的表。理想情况下,我希望在MySQL中创建别名'dbo_customers',它将指向也在MySQL中的customers表。

明确一下,我想像这样在查询中给表起别名:

SELECT * FROM customers AS dbo_customers

但是我希望能够发出以下查询:

SELECT * FROM dbo_customers

并使其返回来自客户表的数据。


8
为何不重命名这张桌子? - OMG Ponies
5
有些情况下,重命名数据库表并不能解决问题。例如,如果你同时使用两个具有不同命名规范的ORM系统,你需要为它们都设置别名才能顺利工作。在这种情况下,顺便说一句,接受的解决方案对我来说已经足够好了 :) - Nimo
1
@OMGPonies 我们计划在未来对许多数据库对象进行大规模重命名,同时仍在编写新查询。对于多租户应用程序中的多个生产数据库中的许多表进行重命名是一件大事,因此我们计划先逐步进行逻辑上的重命名或(别名),以便在进行大型表重命名之前可以更新 SQL 代码。 - Carlos Muñoz
8个回答

44

就我个人而言

CREATE VIEW dbo_customers AS
SELECT * FROM customers

也许不是最好的解决方案,但由于视图可更新,所以应该能够工作。 对于只读肯定有效。


我在最初的帖子中应该说过,我必须能够更新数据。我不认为视图能满足我的需求——除非视图可以以某种方式进行更新? - rswolff
我真的不认为这是最简单的解决方案。 - David-W-Fenton
2
这绝对是最简单的,David。它的行为几乎与原始表格完全相同。您可以向其写入数据,在各种查询中连接它等等。就性能而言,我不太确定,但从软件和查询的角度来看,对于大多数目的,视图与真实表格几乎无法区分。 - Shayne
3
为什么这会是一个不好的解决方案?它似乎完美地回答了问题。它效率低吗?我正在使用一个传统系统,原始开发者为了“安全性通过混杂”,将用户信息表命名为一长串随机字符。我希望能够将其命名为“users”。(由于各种原因,不能重命名现有表格。) - Stephen R
如果您在存储过程中使用此功能,则多个人无法同时访问该存储过程。 - kaushalpranav

10
你可以创建一个“视图”(View)。
CREATE VIEW dbo_customers AS SELECT * FROM customers;

如果这对您不起作用,您可以尝试创建表的影子副本,并使用触发器来保持表同步。
例如:
CREATE TABLE t1( id serial primary key, field varchar(255) not null );
CREATE TABLE dbo_t1( id serial primary key, field varchar(255) not null );

-- INSERT trigger
CREATE TRIGGER t1_dbo_insert AFTER INSERT ON t1
FOR EACH ROW BEGIN
    INSERT INTO dbo_t1 SET field = NEW.field;
    -- No need to specify the ID, it should stay in-sync
END

-- UPDATE trigger
CREATE TRIGGER t1_dbo_update AFTER UPDATE ON t1
FOR EACH ROW BEGIN
    UPDATE dbo_t1 SET field = NEW.field WHERE id = NEW.id;
END

-- DELETE trigger
CREATE TRIGGER t1_dbo_delete AFTER DELETE ON t1
FOR EACH ROW BEGIN
    DELETE FROM dbo_t1 WHERE id = OLD.id;
END

这并不是一个完美的“别名”,但如果其他方法都失败了,这是一个选择。


3

对于MySQL,有一个更简单的解决方案,可以使用MERGE表引擎:

假设我们有一个名为rus_vacancies的表,需要它的英文版本。

create table eng_vacancies select * from rus_vacancies;
delete from eng_vacancies;
alter table eng_vacancies ENGINE=MERGE;
alter table eng_vacancies UNION=(rus_vacancies);

现在表 rus_vacancies 在任何读写操作中等于表 eng_vacancies

唯一的限制是原始表必须具有 ENGINE=MyISAM(可以通过 "alter table rus_vacancies ENGINE=MyISAM" 轻松完成)


1

虽然别名很方便,但是MySQL没有这样的功能。

除了创建视图之外,可能满足您需求的一个选项是在本地使用FEDERATED存储引擎

CREATE TABLE dbo_customers (
    id     INT(20) NOT NULL AUTO_INCREMENT,
    name   VARCHAR(32) NOT NULL DEFAULT '',
    PRIMARY KEY  (id),
)
ENGINE=FEDERATED
DEFAULT CHARSET=latin1
CONNECTION='mysql://fed_user@localhost:9306/federated/customers';

目前 FEDERATED 存储引擎 存在一些限制。以下是其中几个尤其重要的:

  • FEDERATED 表不支持事务
  • FEDERATED 表无法与查询缓存一起使用

1
您可以创建一个名为dbo_customersview,其支持customers表。

1

@OMG Ponies ponies在评论中说:

为什么不重命名表呢?

...对我来说这似乎是显而易见的答案。

如果您为MySQL表客户创建ODBC链接表,它将被称为客户,并且您只需要将表重命名为dbo_customers。我完全看不出有必要为此在MySQL中创建视图。

话虽如此,如果Access应用程序在MySQL表未命名相同的情况下使用SQL Server表名称,那就很令人困惑,并且会导致维护问题(即,在Access前端中链接表与MySQL表尽可能具有相同的名称更简单)。如果我处于您的位置,我会获取搜索和替换实用程序,并在整个Access前端中将所有SQL Server表名称替换为MySQL表名称。您可能需要逐个表格进行操作,但在我看来,现在花费的时间将在开发Access前端时获得更清晰的回报。


2
一个常见的使用情况是,您要检出到旧的提交并需要使您的数据库与旧的代码库配合工作。 - Handsome Nerd

1

我总是在Access中将我的“链接到SQL”表从{dbo_NAME}重命名为{NAME}

链接会创建表名为{dbo_NAME},但Access偶尔会出现与dbo_前缀有关的问题。


0

我想提及一个我尝试过但已放弃的糟糕解决方案,即对应于我的表的 .frm、.MYD 和 .MYI 文件上使用硬链接,路径在 /var/lib/mysql/{name_of_my_database}/

然而这种方法不起作用。对于 InnoDB 表,它根本无法工作(即使你对 .idb 文件进行硬链接),因为表也会被引用到 ibdata1 中。

对于 MyISAM 表,它有点起作用,但实际上并没有,因为在内存中,表仍然是不同的,因此不会共享缓存。因此,如果您向 original_table 写入一行,则不会立即出现在 aliased_table 中。您必须首先刷新表... 这就打败了这个方法,甚至会导致数据丢失(如果您在刷新之前在原始表和别名表中插入一行,则只保留一行)。

我认为我的实验值得一提,以作为一个警示故事。


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