2

我对此很陌生,一个好朋友处于困境中。我已经黔驴技穷了。我已经使用像navicat 和sqlyog 这样的gui 来执行此操作,但只能手动操作。

他的乐队信息数据(时间表等)位于服务器(管理服务器)上的 MYSQL 数据库中。

我正在为他建立一个用 Perl 编写的基本站点,该站点从驻留在我的服务器(公共服务器)上的数据库中获取数据,并显示日程安排信息、以前的演出时事通讯和一些粉丝互动。

他使用他喜欢并希望保留的管理界面来管理管理服务器上的数据。

管理服务器数据库有一堆表,甚至公共数据库不需要的表数据。

所以,我在公共端创建了只包含相关数据的表。

我基本上使用 gui 来导出数据,然后每当他对管理数据库进行更新(复制和粘贴)时插入到公共端。

(仅供参考,我正在使用 DBI 模块来访问/通过我的公共 db perl 脚本中的数据。)

我可以直接访问管理服务器以仅获取我需要的数据,但是,这样做的全部目的是“镜像”数据,而不是在每次查询时访问管理服务器。此外,有些表有数千行,在循环中解析每一行对我来说似乎太“笨重”了。然而,有一个“时间”列可以用来比较。

由于结构不同,我无法“同步”,我只需要三个表中的相关表数据。

所以......我渴望自动化!

我读“复制”是一种快速的方法,但是我在如何实施方面的发现对于我的水平来说太先进了。

我没有在管理服务器上放置脚本来通知何时有更新的奢侈。

1-我想设置一个脚本来检查一个表,看看管理服务器数据库上是否更新或添加了一行。然后,我希望将新的或更改的数据更新或插入到公共服务器数据库中。

这个“检查”可以在我猜想或在公共端加载特定页面时触发的 cron 作业中设置。(我假设由 cron 调用的相同子例程)。

这些数据不需要是“实时的”,但是,如果他更新了一些东西,最好让它尽快出现。

我已经做了很多阅读、模块研究和实验,但是,我又回到了 stackoverflow,在那里我总是能得到很好的建议和例子。

许多术语仍然让我无法理解,因此带有解释的详细示例确实可以帮助我更快地学习。

提前致谢。

4

4 回答 4

1

我认为您将 ETL 误解为一个复杂的问题域,而将 ETL 视为一次性解决方案,这通常不比写报告难多少。除非我完全误解了您的问题,否则您不需要通用的 ETL 解决方案,您需要一个适用于少数表和几千行的一次性解决方案。ETL 和 Schema 映射听起来比单一工作更可怕。(ETL 的泛化、扩展、变更管理和 OLTP 到 OLAP 支持是特别困难的地方。)如果您可以使用 Perl 从 SQL 数据库中编写报告,那么您可能知道足以处理 ETL涉及到这里。

1-我想设置一个脚本来检查一个表,看看管理服务器数据库上是否更新或添加了一行。然后,我希望将新的或更改的数据更新或插入到公共服务器数据库中。

如果您需要从中提取的每个表都有一个更新时间戳列,那么您的 cron 作业包含一些带有 WHERE 子句的 SELECT 语句,这些语句基于 cron 作业的最后一次运行以仅获取更新。没有更新时间戳的表可能需要完整转储。

除非需要规范化,否则我会使用一对一的表映射......在我看来更简单。如果您不必这样做,为什么要通过“大”模式更改使其复杂化?

有些表是数千行,在循环中解析每一行对我来说似乎太“笨重”了。

将您的查询限制在您需要的列(如果没有 BLOB 或您需要的特别大的列),通过 DBI 使用 FETCHALL 方法,几千行应该不是问题。在本地循环所有你想要的,尽可能少地访问远程数据库。

如果一行的日期较新,请更新它。我还必须检查插入的新行。

每张桌子都需要一张SELECT ... WHERE updated_timestamp_columnname > last_cron_run_timestamp。该结果集将包含所有具有较新时间戳的行,其中包含新插入的行(如果时间戳列的行为与我预期的一样)。要更新本地数据库,请查看 MySQL 的ON DUPLICATE KEY UPDATE语法……这将让您一步完成。

...如何实施对我的水平来说太先进了...是的,我实际上已经这样做了,但是我必须手动更新...

一些问题可以帮助我们了解您的水平...您是从 mysql 客户端命令行还是从 GUI 访问数据库?您是否已经到了将 SQL 查询包装在 Perl 和 DBI 中的地步?

于 2011-01-04T05:59:30.133 回答
1

您正在寻找的两个术语是“复制”或“ETL”。

一是复制方式。

假设您的管理服务器有表 T1、T2、T3,而您的公共服务器有表 TP1、TP2。

所以,你想要做的(因为你有不同的表结构,正如你所说)是:

  1. 从公共服务器获取表,并在管理服务器(TP1 和 TP2)上创建这些表的精确副本。

  2. 在管理服务器的原始表上创建一个触发器,将 T1/T2/T3 中的数据填充到管理服务器的 TP1/TP2 副本中。

  3. 您还需要将初始数据从 T1/T2/T3 填充到管理服务器的 TP1/TP2 副本中。呃。

  4. 设置从管理服务器的 TP1/TP2 到公共服务器的 TP1/TP2的“复制”

另一种方法是编写一个程序(此类程序称为 ETL - Extract-Transform-Load),它将从管理服务器(“ETL”的“E”部分)上的 T1/T2/T3 提取数据,按摩数据转换成适合加载到 TP1/TP2 表的格式(“ETL”的“T”部分),将这些文件传输(通过 ftp/scp/whatnot)到公共服务器,以及程序的后半部分(“L”)部分将文件加载到公共服务器上的表 TP1/TP2 中。程序的两半将由您选择的调度程序cron或您选择的调度程序启动。

有一篇关于如何开始构建 Perl/MySQL ETL 的很好示例的文章:http: //oreilly.com/pub/a/databases/2007/04/12/building-a-data-warehouse-with-mysql- and-perl.html?page=2

如果您不想自己构建,这里有一个开源 ETL 系统列表,从未使用过其中任何一个,因此对它们的可用性/质量没有意见:http: //www.manageability.org/blog/stuff/open-source-等

于 2010-12-31T15:34:50.533 回答
0

如果两个数据库不同,您将需要一个 ETL 解决方案来从一个模式映射到另一个模式。

如果模式相同,您所要做的就是将数据从一个复制到另一个。

于 2010-12-31T15:35:39.363 回答
0

为什么不在“从”服务器上创建与主服务器相同的结构。然后创建一个小表来跟踪更新表的最后时间戳或 id。

然后从 master 中选择自上次时间戳以来更改或大于 id 的所有行。将它们插入从服务器上的匹配表中。

您需要注意更新的行。如果 master 上的一行被更新但时间戳没有改变,那么你将如何判断要获取哪些行?如果这不是问题,则过程非常简单。

如果这是一个问题,那么您需要更加复杂,但在不了解数据结构和更新机制的情况下,它会在上面给出指示。

cron 可以每隔一段时间调用该脚本来更新更改。

如果两台服务器上的数据库结构必须不同,则可能需要添加一个简单的转换步骤,但大多数情况下可以在 sql select 语句中完成,也可能是一两个连接。

于 2011-01-04T02:10:28.893 回答