数据表迁移数据一致性验证
在迁移数据库的时候做一些必要的验证还是很有用的,比如说迁移前后的数据条数是否一致,数据是否一致,这个时候怎么办呢,验证条数还好说,要是验证数据是否一致呢,对于重要的数据当然要每条都不会有差错,随机抽样验证肯定是不行的,万一遗漏了就麻烦了,而且两张表不再同一台服务器上。这个时候该怎么办呢,有一种方法:
- 从表中选取几个重要字段,比如说A、B、C,用这几个字段作为比对的标尺。
- 从原表中导出每条数据的这三个字段到一个文件f1中。
- 从目的表中到处每条数据的这三个字段到文件f2中。
- 比对文件f1、f2文件中的每条数据是否相同。
- 得出结论
上面这种方法是同时想出来的,也还不错,但我觉得还有改进的余地:
- 首先就是不是所有字段,仍然有可能在非主要字段出现different。
- 整体效率比较低
我的想法是这样:
- 对表中的每n条数据进行拼接(直接连接起来,n取值取决于每条数据的数据量大小)。
- 计算这n条数据的md5值,添加到文件f1中,直到所有数据取值完成。
- 对目的表也一样,记录的文件f2中。
- 比对文件f1、f2文件的md5值,如果一致,ok,成功。
- 如果不一致,从上倒下比对每条md5值,找到第m条不一致。
- 得出结论,不一致的数据在m*(n-1)+1 ~ m*n之间,可以再次选择定位。
第二种方法的好处就是输出文件会在一定范围缩小,比对方便,但是也有缺点,不能像第一种方法一样直接通过关键字段定位不同数据的位置。
下面是第二种方法效果和的具体代码实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | <?php /** * 使用方法: * php -f mysql_diff.php yes dir 10 * 是否计算条数 是否计算输出d5并保存到文件 合并数据的级别 * */ if (php_sapi_name() != 'cli' ) { die ( "请在CLI模式下运行" ); } array_shift ( $argv ); if ( empty ( $argv )) { die ( "at letase contain one info" ); } $is_count = array_shift ( $argv ); $is_md5 = empty ( $argv ) ? false : array_shift ( $argv ); $conbine_num = empty ( $argv ) ? 1 : intval ( array_shift ( $argv )); if ( $is_md5 && ! is_dir ( $is_md5 ) && ! mkdir ( $is_md5 , 777, true)) { die ( "error info : md5 info must be input to a file" ); } $dbinfos = array ( 'host' => 'localhost' , 'port' => '3306' , 'user' => 'root' , 'pswd' => '123456' , 'charset' => 'utf8' , 'tables' => array ( 'lagou.pos' , 'lagou.pos_innodb' , ), ); //验证格式 if (! $link = mysql_connect( $dbinfos [ 'host' ]. ":" . $dbinfos [ 'port' ], $dbinfos [ 'user' ], $dbinfos [ 'pswd' ])) { die ( "connect to [{$host}@{$port}] failed!!" ); } if (!mysql_query( "set names {$dbinfos['charset']}" )) { die ( "set charset error : " .mysql_error()); } foreach ( $dbinfos [ 'tables' ] as $table ) { if ( $is_count ) { $sql = "select count(*) as nums from {$table}" ; $ret = mysql_query( $sql ); if (! $ret ) { die ( "error : " .mysql_error()); } $ret = mysql_fetch_array( $ret , MYSQL_ASSOC); echo "{$table} : {$ret['nums']}\n" ; } if ( $is_md5 ) { $path = $is_md5 .DIRECTORY_SEPARATOR. $table ; $sql = "select * from {$table}" ; $ret = mysql_query( $sql ); $flag = 0; $fields = '' ; while ( $_ret = mysql_fetch_array( $ret , MYSQL_NUM)) { $flag ++; while ( $_ret ) { $fields .= array_pop ( $_ret ); } if ( $flag % $conbine_num == 0) { file_put_contents ( $path , md5( $fields ). "\n" , FILE_APPEND); $fields = '' ; } } if ( $flag % $conbine_num != 0 && $flag > 0) { file_put_contents ( $path , md5( $fields ). "\n" , FILE_APPEND); } echo "save to file info : " . realpath ( $path ). "\n" ; } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述