【发布时间】:2016-05-10 08:52:37
【问题描述】:
我想将大型数据库中的一些表迁移到另一个结构中。为了向后兼容,我想通过视图公开旧结构。现在我想看看这个视图是否正在被使用,所以如果它不再使用,我可以 DROP 它。由于数据库大小和架构的原因,无法放上查询日志。
有没有办法做到这一点? IE。在该视图上的 select 上或任何其他方式将记录插入到 accesslog 表中。
【问题讨论】:
我想将大型数据库中的一些表迁移到另一个结构中。为了向后兼容,我想通过视图公开旧结构。现在我想看看这个视图是否正在被使用,所以如果它不再使用,我可以 DROP 它。由于数据库大小和架构的原因,无法放上查询日志。
有没有办法做到这一点? IE。在该视图上的 select 上或任何其他方式将记录插入到 accesslog 表中。
【问题讨论】:
您可以将函数用作视图中的列来在表中写入日志条目。
create table LogView (
Viewname varchar(50) not null,
Username varchar(50) not null,
dt datetime,
primary key (Viewname, Username)
);
delimiter $$
create function fctViewLog(Viewname varchar(50)) returns int deterministic
begin
insert into LogView (Viewname, username, dt)
values (Viewname, Current_User(), now())
on duplicate key update dt = now();
return 0;
end $$
Delimiter ;
create view ViewOldTable as (
select ..., fctViewLog('ViewOldTable') as JustForLogging from YourNewTable);
这将为您的视图添加一个值为 0 的列。如果该新列是一个问题,您可以使用视图中的现有列并返回其值。如果您的视图有任何整数值,例如id,你可以使用:
create function fctViewLog(Viewname varchar(50), in_value int) returns int deterministic
begin
insert into LogView (Viewname, username, dt)
values (Viewname, Current_User(), now())
on duplicate key update dt = now();
return in_value;
end $$
Delimiter ;
create view ViewOldTable as (
select ..., fctViewLog('ViewOldTable', id) as id
from YourNewTable);
那么您的列的数量和名称将保持不变。
它将为您的视图增加可测量的开销,因为它会更新您视图中每一行的 LogTable,但这只会在使用旧结构而不是新结构时发生,我猜这是主要关注点;并且它可能具有敦促用户更新客户端的副作用。您可以通过例如优化它。当条目存在时不更新 dt-row(例如,如果时间并不重要),但它仍然会减慢它。
【讨论】:
mysql 的免费版本仅提供通用查询日志,用于记录发送到服务器的任何语句。调用视图不会导致任何可捕获事件,因此您无法填充自己的查询日志。我看到您可能会遵循 3 个选项:
使用存储过程而不是视图来返回数据。在存储过程中,您可以进行日志记录,还可以返回结果集。显然,您无法轻松加入或过滤结果集。
获取企业版 mysql 并安装 the audit log plugin 以获得对性能更友好的日志记录选项。这样您就可以检查您的视图是否仍在使用。
说实话,我不一定会跟踪这些视图的使用,尤其是如果您打算最终关闭它们。给用户一个时间表,直到视图可用,在截止日期临近时经常提醒他们,并在指定的截止日期禁用视图。如果任何用户有一个基于视图的完善的解决方案,他们将不愿意改变它,除非你强迫他们。
【讨论】: