MySQL实现全量同步和增量同步到SQL Server或其他关系型库

在将MySQL中的两张表同步到SQL Server的过程中,全量同步和增量同步各有其优缺点。全量同步简单直接但可能耗时较长且资源消耗大,而增量同步则更加高效但需要额外的逻辑来处理数据的变更。以下是对这两种同步方式的详细解释及代码示例的完善。

完整代码示例

以下是一个完整的示例,包括全量同步和增量同步,以及使用schedule库来设置定时任务。

python 复制代码
import pymysql
import pyodbc
from datetime import datetime, timedelta
import schedule
import time

# MySQL 数据库连接函数
def get_mysql_connection():
    return pymysql.connect(
        host='localhost',         # 替换为你的 MySQL 服务器地址
        user='root',              # 替换为你的 MySQL 用户名
        password='password123',   # 替换为你的 MySQL 密码
        database='test_db'        # 替换为你的 MySQL 数据库名
    )
 
# SQL Server 数据库连接函数
def get_sqlserver_connection():
    return pyodbc.connect(
        'DRIVER={ODBC Driver 17 for SQL Server};'
        'SERVER=your_sqlserver_host;'  # 替换为你的 SQL Server 服务器地址或 IP
        'DATABASE=test_sqlserver_db;'  # 替换为你的 SQL Server 数据库名
        'UID=sqlserver_user;'          # 替换为你的 SQL Server 用户名
        'PWD=sqlserver_password123'    # 替换为你的 SQL Server 密码
    )

# 全量同步函数
def full_sync_tables():
    mysql_conn = get_mysql_connection()
    sqlserver_conn = get_sqlserver_connection()
    try:
        mysql_cursor = mysql_conn.cursor()
        sqlserver_cursor = sqlserver_conn.cursor()
        
        # 清空SQL Server中的表数据
        sqlserver_cursor.execute("TRUNCATE TABLE table1")
        sqlserver_cursor.execute("TRUNCATE TABLE table2")
        
        # 从MySQL表中查询所有数据并插入到SQL Server表中
        for table in ['table1', 'table2']:
            mysql_cursor.execute(f"SELECT * FROM {table}")
            mysql_data = mysql_cursor.fetchall()
            columns = len(mysql_cursor.description)
            placeholders = ', '.join(['?'] * columns)
            insert_query = f"INSERT INTO {table} VALUES ({placeholders})"
            for row in mysql_data:
                sqlserver_cursor.execute(insert_query, row)
        
        sqlserver_conn.commit()
    finally:
        mysql_cursor.close()
        mysql_conn.close()
        sqlserver_cursor.close()
        sqlserver_conn.close()

# 增量同步函数
def incremental_sync_tables(last_sync_time):
    mysql_conn = get_mysql_connection()
    sqlserver_conn = get_sqlserver_connection()
    try:
        mysql_cursor = mysql_conn.cursor()
        sqlserver_cursor = sqlserver_conn.cursor()
        
        # 获取MySQL中自上次同步以来的增量数据
        for table in ['table1', 'table2']:
            mysql_cursor.execute(f"SELECT * FROM {table} WHERE update_time > %s", (last_sync_time,))
            mysql_data = mysql_cursor.fetchall()
            
            # 插入或更新SQL Server中的数据
            update_query = f"UPDATE {table} SET {} WHERE id = ?".format(
                ', '.join([f"{col} = ?" for col in mysql_cursor.description[1:]]))
            insert_query = f"INSERT INTO {table} ({}) VALUES ({})".format(
                ', '.join([col[0] for col in mysql_cursor.description]),
                ', '.join(['?'] * len(mysql_cursor.description)))
            
            for row in mysql_data:
                sqlserver_cursor.execute(f"SELECT id FROM {table} WHERE id = ?", (row[0],))
                result = sqlserver_cursor.fetchone()
                if result:
                    sqlserver_cursor.execute(update_query, row[1:] + (row[0],))
                else:
                    sqlserver_cursor.execute(insert_query, row)
        
        # 处理删除操作(假设MySQL有逻辑删除标记字段is_deleted)
        for table in ['table1', 'table2']:
            sqlserver_cursor.execute(f"SELECT id FROM {table}")
            sqlserver_ids = [row[0] for row in sqlserver_cursor.fetchall()]
            mysql_cursor.execute(f"SELECT id FROM {table} WHERE is_deleted = 1 AND update_time > %s", (last_sync_time,))
            deleted_ids = [row[0] for row in mysql_cursor.fetchall()]
            for id_ in set(sqlserver_ids) - set(deleted_ids):
                sqlserver_cursor.execute(f"DELETE FROM {table} WHERE id = ?", (id_,))
        
        sqlserver_conn.commit()
    finally:
        mysql_cursor.close()
        mysql_conn.close()
        sqlserver_cursor.close()
        sqlserver_conn.close()

# 定时任务函数
def schedule_sync_tasks():
    # 每天凌晨1点进行全量同步
    schedule.every().day.at("01:00").do(full_sync_tables)
    
    # 每5分钟进行增量同步
    last_sync_time = datetime.now() - timedelta(minutes=5)  # 初始化为5分钟前,之后每次调用都会更新
    def run_incremental_sync():
        nonlocal last_sync_time
        incremental_sync_tables(last_sync_time)
        last_sync_time = datetime.now()  # 更新上次同步时间
    schedule.every(5).minutes.do(run_incremental_sync)

    # 运行调度器
    while True:
        schedule.run_pending()
        time.sleep(1)

# 运行定时任务
if __name__ == "__main__":
    schedule_sync_tasks()

注意事项

  1. 性能:对于大数据量的表,增量同步可能会更高效,但也要确保增量同步的逻辑不会成为瓶颈。
  2. 事务:在同步过程中,确保使用事务来保持数据的一致性。
  3. 错误处理:在实际应用中,需要更完善的错误处理和日志记录机制。
  4. 时间戳 :确保MySQL中的update_time字段在每次数据更新时都被正确更新。
  5. 健壮性:增量同步依赖于时间戳或逻辑删除标记,因此需要确保这些字段在业务逻辑中被正确维护。
  6. 安全性:不要在代码中硬编码数据库密码,考虑使用环境变量或配置文件来管理敏感信息。
相关推荐
爱笑的眼睛1118 小时前
超越剪枝与量化:下一代AI模型压缩工具的技术演进与实践
java·人工智能·python·ai
yaoh.wang18 小时前
力扣(LeetCode) 14: 最长公共前缀 - 解法思路
python·程序人生·算法·leetcode·面试·职场和发展·跳槽
雨大王51218 小时前
工业生产执行系统(MES)在汽车制造行业的应用案例
运维·人工智能
reasonsummer18 小时前
【办公类-18-07】20251215(Python)“口腔检查涂氟信息”批量生成打印(区名、学号、姓名、学校、班级、身份证、户籍、性别、民族)
开发语言·python
数据堂官方账号19 小时前
AI赋能工业4.0:数据堂一站式数据服务加速制造智能化落地
人工智能·机器人·数据集·人机交互·数据采集·数据标注·工业制造
老赵聊算法、大模型备案19 小时前
2025 年 12 月北京市生成式人工智能服务备案分析:政务场景再扩容,合规生态更聚焦
人工智能·算法·microsoft·aigc·政务
soft200152519 小时前
从一次增删改操作开始:彻底理解 MySQL Buffer Pool 的地位与作用
数据库·mysql
Rabbit_QL19 小时前
【PyTorch】detach:从计算图中切断梯度的原理与实践
人工智能·pytorch·python
晨曦54321019 小时前
MySQL与Python数学函数大比拼
python·mysql
q_191328469519 小时前
基于SpringBoot2+Vue2的行业知识答题考试系统
java·vue.js·spring boot·mysql·毕业设计·计算机毕业设计·演示文稿