Php 比较两个不同类型的数据库表并比较其数据的最佳方法?

Php 比较两个不同类型的数据库表并比较其数据的最佳方法?,php,mysql,sql-server,drupal-6,Php,Mysql,Sql Server,Drupal 6,我有两个数据库表,一个在MYSQL中,一个在MSSQL中。两者都有相似的数据,其中一个基于另一个的数据。它们位于两个不同的数据库中,因为其中一个是管理的远程系统,而本地系统是Drupal安装,我使用它通过自定义模块以更友好的方式显示数据 例如,我在MSSQL中有一个这种结构的表: ID | Title | Description | Other fields I don't care about 在从这个表中提取数据的基础上,我在MYSQL中生成了一个表: local_id | remote_

我有两个数据库表,一个在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)
然后我们需要至少一个其他事务来获取新记录(如果在上一个循环中没有更新,我也可以在这里更新):

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)

这是一个很大的数据库活动。如果表格是同一类型的话会更容易些,但事实上这是我知道的唯一方法。有更好的办法吗?我是否可以将两个结果集拉入一个关联数组并进行比较,然后只执行删除和创建所需的事务?我不确定。

您可以执行基于集合的操作,而不是逐行操作。e、 g

INSERT INTO local_table (vales)
SELECT .. FROM  remote_table
WHERE NOT EXISTS (Select ... FROM local_table WHERE remote_table.field = local_table.field and ...)
为此,您需要添加一个链接服务器,请参见。您可以创建从SQL Server到页面上列出的任何服务器的链接。这包括任何具有ODBC驱动程序的数据库,MySQL就是这样做的


我不知道MySQL是否能够做相反的操作。

您可以做基于集合的操作,而不是逐行操作。e、 g

INSERT INTO local_table (vales)
SELECT .. FROM  remote_table
WHERE NOT EXISTS (Select ... FROM local_table WHERE remote_table.field = local_table.field and ...)
为此,您需要添加一个链接服务器,请参见。您可以创建从SQL Server到页面上列出的任何服务器的链接。这包括任何具有ODBC驱动程序的数据库,MySQL就是这样做的


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

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

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

看看MySQL替换,插入到。。我不知道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 

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

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

看看MySQL替换,插入到。。我不知道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 

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