【问题标题】:Best way to compare two database tables of differing types and compare their data?比较两个不同类型的数据库表并比较它们的数据的最佳方法?
【发布时间】:2011-09-02 16:46:33
【问题描述】:

我有两个数据库表,一个在 MYSQL,一个在 MSSQL。两者都有相似的数据,一个基于另一个数据。它们位于两个不同的数据库中,因为一个是管理的远程系统,而本地系统是 Drupal 安装,我使用它通过自定义模块以更友好的方式显示数据。

例如,我在 MSSQL 中有一个这种结构的表:

ID | Title | Description | Other fields I don't care about

基于从该表中提取数据,我在 MYSQL 中生成了一个表:

local_id | remote_id | title | description

当模块初始化时,它会从 MSSQL 表中进行选择并生成记录并填充本地数据库。 Remote_id 是 MSSQL 数据库中的 ID 字段,因此我们可以将两条记录一起引用。

我需要同步这些数据,在本地删除远程表上不再存在的记录并创建本地不存在的新记录,并更新所有行信息。

问题是,这需要至少 2 个不同的事务以及可能的逐行事务。示例:

将本地同步到远程并删除不存在的远程记录:

Select remote_id from local_table;
  For Each remote_id ( select ID, title, description FROM remote_table where ID = remote_id )
    If record exists
      UPDATE local_table WHERE remote_id = row_id
    Else
      DELETE FROM local_table where remote_id = row_id

那么我们至少需要一个其他事务来获取新记录(如果我在上一个循环中没有这样做,我也可以在这里更新):

Select ID, title, description from remote_table;
  For each ID ( Select remote_id from local_table )
    If does not exist
      INSERT INTO local_table (VALUES)

所以这是很多数据库活动。如果表格是相同的类型会更容易,但这是我知道如何做到这一点的唯一方法。有没有更好的办法?我可以将两个结果集都拉到一个关联数组中并以这种方式进行比较,并且只执行删除和创建所需的事务吗?我不确定。

【问题讨论】:

  • 为什么不直接查询远程数据库?
  • 我不确定你的意思,纳尔夫。我需要同时查询远程和本地数据库来比较两者。我正在寻找最有效的方法。
  • 我的意思是你为什么要获取表的本地副本?很明显,您可以直接远程访问它...
  • @Narf - 我正在尝试将远程数据引入 drupal 安装。为了创建节点,它必须将远程数据带入本地数据库并将它们保存为节点。我需要将远程行与我当前在站点上创建的节点进行比较,并相应地编辑或删除它们。我可以直接访问数据库(我现在正在这样做),但它限制了在 drupal 系统中执行操作的能力,除非您将数据作为节点引入。

标签: php mysql sql-server drupal-6


【解决方案1】:

根据您的系统,有很多方法可以做到这一点。 我所做的第一个假设是您有 2 个数据库,并且您希望在这 2 个数据库之间同步数据 也就是说,MSSQL db 必须从 MySQL 中提取数据,反之亦然

您使用关联数组的方法很好,但如果表中有 100 列怎么办? (在您的情况下不是,但该方法不是未来的证明) 因此,要更新 1 行,如果有 100 行,则需要进行“n”列比较,那么将有 100*n 比较

看看 MySQL REPLACE, INSERT INTO .. ON DUPLICATE KEY 子句可能对你有帮助 - 我不知道 MSSQL 中是否有这样的子句

您可以执行其他操作,例如 - 在每个数据库表中都有一个“last_updated”列 - 每当表中的列更新时,必须更新此时间戳字段

通过这种方式,您可以判断任一数据库表中的行是否已更新(通过将其与旧时间戳值进行比较)并仅更新这些行

逻辑将在这些行中

to sync local to remote 
foreach localrow 
  get the common_id of the row 
  get the timestamp of the row 
  check if a row with this common_id exists in the remote table 
  if no then insert 
  if yes then 
    compare timestamps between local and remote row 
    if local row timestamp > remote row timestamp then update remote row 

【讨论】:

    【解决方案2】:

    您可以进行基于集合的操作,而不是逐行操作。例如

    INSERT INTO local_table (vales)
    SELECT .. FROM  remote_table
    WHERE NOT EXISTS (Select ... FROM local_table WHERE remote_table.field = local_table.field and ...)
    

    为此,您需要添加链接服务器,请参阅sp_addlinkedserver。您可以创建从 SQL Server 到页面上列出的任何服务器的链接。这包括任何具有 MySQL 的 ODBC 驱动程序的数据库。

    我不知道 MySQL 是否能够做相反的事情。

    【讨论】:

    • 我不相信这会起作用,因为没有办法集成 remote_table 数据,因为它需要单独的 DB 调用,因为一个在 SQL Server 中,另一个在 MySQL 中。您不能在 mysql_query 语句中同时执行这两项操作……可以吗?
    • @Oranges13。我已经更新了我的答案。希望我已经使链接服务器更加清晰,它允许您跨数据库进行连接
    • 我仍然认为这在 drupal 安装的上下文中是不可能的。我不相信我可以将这样的东西输入drupal 的数据库抽象函数并让它成功运行。而且我不能以任何形式修改数据库,所以我不相信这会起作用。
    • 一旦您设置了链接服务器,它就像调用存储过程或访问 SQL Server 上的对象一样。 Drupal 应该能够处理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 2023-04-02
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多