我的应用环境是这样的。  2个不同类型的客户端,  甲客户端 不断的检查自己机器的情况 将相关信息 上传到数据库,这个可以判断是否信息发生变化,如果发生变化再上传信息,所以效率不成问题。  乙客户端 不停地查询数据库中甲上传的信息,当发现数据发生变化时,就把自己机器上信息同步为数据里的信息。问题来了,有没有 办法 不用不停的查询,或者 不需要查询所有的数据在比对是否有变化,有没有简单办法 判断某个表的数据是否有变化? 因为 提取出来的数据 比如是一个字段 并且是一个数据集,这样检查是否发生变化,感觉每秒传递的数据量是不是大了点。有没有更好的办法呢,欢迎大家指教。

解决方案 »

  1.   

    还不如同步,你这种方法,消耗资源,占用CPU
      

  2.   

    1. 能否考虑直接由 甲 直接同时更新 甲,乙的数据库? (估计不行,如果 甲 客户软件不是由自己开发的)
    2. 是否可以降低数据同步的时延,比如可否降至分钟级而不是秒级?如果可以这样,则可以直接用MySQL数据库同步。 http://dev.mysql.com/doc/refman/5.1/zh/replication.html 第6章:MySQL中的复制3. 在 甲 数据库 所在服务器上,打开二进制日制功能,然后用一个程序每秒检查一下这个二进制日志文件的更新日期,这个不占什么资源。如果更新了,则从二进制文件中提取SQL语句,对 乙的数据库 进行更新。4. 下载mysql源代码,进行修改,(比较复杂)4. 下载 MyISAM的源代码,进行修改 (比上面的容易一点,但也复杂) 
      

  3.   

    看来我理解错了,你能否举例说明一下你想实现的功能是什么?1. 甲 机向数据库写入一条记录 r1 
    2. 乙 机不停地查询,发现这个更新 r1 
    然后如何处理?把r1 更新到  乙 机的什么中? 还是把 乙 机上信息更新到 r1 ? 乙 机上信息在哪里(本地数据库中?)?
      

  4.   

    或者创建一个内存表,如:
    create table if not exists memtemp(id enum('1') not null default 1,serial int(8) unsigned not null)engine=memory
    当甲每次更新数据时,同时更新一下这个 memtemp : update memtemp set serial=serial+1
    乙机每秒读取一次 memtemp.serial,当这个值与上一次读出来的值不同,表示数据已经更新,就执行更新操作.这样的好处是每次检查数据有没有更新的时候,传输的数据量不大.
    看看这样对你有没有帮助.
      

  5.   

    修改一下:
    创建内在表: create table if not exists memtemp(id enum('1') not null default '1',serial int(8) unsigned not null,unique key id(id))engine=memory;改过后的memtemp 表就只可以有一行,就是 id='1',不可能再有别的行.
    这个表的数据在内存中,所以每次重启数据库,这个表都会变成空表,在甲开始运行时都要插入一条同时也是唯一的一条数据,
    而且也可以根据这个表是不是空表,就可以知道甲有没有运行了.
      

  6.   

    个人感觉这是个代价折衷的问题,甲客户端在写,乙客户端要求读到最新的数据,但矛盾的是mysql无法通知外界自己数据的变化,因此,你就要乙客户端总是不断的巡查数据库。
    首先有个问题:
    ,甲更新数据库频繁么?
    ,乙一定要实时的获取数据么?能允许的最大延时是多少呢?了解这两个问题就可以确定:
    ,乙程序应该死循环读取,还是定时读取数据库
    ,乙程序应该导出全表还是导出增量导出全表的方法就不用说了,如何导出增量?通常会借助触发器,流程如下
    1)如,甲有条sql是insert table_a
    2)触发触发器,触发器的功能是将该操作记录到一触发表中,该触发表中记录了操作类型,时间戳等你需要的信息
    3)乙客户端读触发表,根据触发表中记录的信息更新自己的数据,而后记录下最后一次处理的触发表中的id,下次从这个id开始读取供参考吧
      

  7.   

    回6、7楼的兄弟的疑问引用 5 楼 tradesignal 的回复:to 4 楼的大侠 
      
       甲 乙都是客户端 连接同一个数据库, 不涉及数据库的同步 怎么理解   乙客户端 不停地查询数据库中甲上传的信息,当发现数据发生变化时,就把自己机器上信息同步为数据里的信息。?类似 甲客户端 有个time属性   mytime  原来是 当 甲更新时乙自动更新成甲一样的信息,但是因为乙不具备公网ip 因此 不能直接推送信息,所以使用了一个具备公网ip的数据库作为数据中转。9、10楼的兄弟的解决方案 是一个可执行方案,我的最初想法也是类似的。11 楼的兄弟 触发器我也考虑过,但是参考最近的一本 mysql权威指南 说 mysql的触发器 有很多局限性,不能想某个表 执行 插入等行为,现在只能执行 替换数据等功能,不知道你是否确定mysql5 的触发器 是否能向表里插入数据。内存表的方式是不是比触发器还要高效呢。另外说明  对数据实时更新是非常严格,希望能做到1秒
      

  8.   

    数据库表数据改变的对比现在是怎么做的?
    甲客户端程序你们可以改吗,如果在甲客户端进行插入修改删除的时候都将SQL语句保存到中转数据库的某表中,然后乙客户端每次读取此表中新SQL,然后执行,这样可行吗
      

  9.   

    触发器是可以做到向表中插入记录的,但触发器会有性能问题,当单条SQL触发大量记录时,会有性能问题,导致延时,其它情况还好
      

  10.   

    同意lgzxz999,甲将执行语句写入日志表,乙定时执行此日志。
    多罗嗦一句,日志表中应该有一个标志字段,以表明此条日志为新日志还是已执行过的。
      

  11.   

    13楼的方式 比较独特。新问题, 当甲插入一条新 记录  操作的sql该怎么保存到表里呢,   乙并不是有本地数据库,直接同步数据库,而是乙直接从数据库中获得数据更新自身的属性。
    但这种方式  我觉的 好像可以用一个表 保存 甲的操作行为 比如  创建一个表 operations  字段  opertion  optype  time  opid 乙是否已执行  这几个字段
    在甲执行 操作的时候 就把 相关信息存进去,关键是执行的操作的id, 比如insert 一条记录,知道该记录的id是最关键的,c中 insert一个条数据时 会返回insert的id吗?mysql基本功比较差,以前用php的 adobe类是可以的,不知道  c里面用什么方法获得这个id
      

  12.   

    若是用PDO连接的可以用它的:lastinsertid()方法mysql语句可以用:select last_insert_id();
      

  13.   

    用Socket 乙启动时和数据库建立连接 在数据库端建立一个负责检索数据库的功能模块 当数据库发生变化是通知乙