it编程 > 数据库 > Mysql

MySQL处理重复数据插入的处理方案

63人参与 2025-04-14 Mysql

1. 引言

在数据库操作中,处理重复数据插入是一个常见的需求。特别是在批量插入数据时,可能会遇到主键冲突或唯一键冲突(duplicate entry)的情况。如何优雅地捕获这类异常并执行相应的业务逻辑,是提高代码健壮性的关键。

本文将以一个实际的python mysql数据库操作为例,分析如何优化异常处理逻辑,使得当出现duplicate entry错误时,能够执行特定的业务方法(如更新记录状态)。同时,我们也会对比java中的类似处理方式,帮助读者更好地理解不同语言下的异常处理机制。

2. 问题背景

2.1 原始代码分析

原始代码的功能是批量插入手机号数据到mysql数据库,其核心逻辑如下:

def insert_into_mysql(phone_numbers, prefix, province, city):
    try:
        connection = get_db_connection()
        cursor = connection.cursor()
        
        data_to_insert = []
        for phone_number in phone_numbers:
            if len(phone_number) == 11:
                suffix = phone_number[-4:]
                data_to_insert.append((prefix, suffix, phone_number, province, city))
        
        cursor.executemany(insert_query, data_to_insert)
        connection.commit()
        return true
    
    except exception as e:
        print(f"插入数据失败: {e}")
        if connection:
            connection.rollback()
        return false
    
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

2.2 存在的问题

3. 优化方案

3.1 目标

3.2 优化后的python代码

def insert_into_mysql(phone_numbers, prefix, province, city, url=none):
    connection = none
    cursor = none
    try:
        connection = get_db_connection()
        if not connection:
            print("数据库连接失败")
            return false

        cursor = connection.cursor()
        data_to_insert = []
        
        for phone_number in phone_numbers:
            if len(phone_number) == 11:
                suffix = phone_number[-4:]
                data_to_insert.append((prefix, suffix, phone_number, province, city))

        if not data_to_insert:
            print("警告: 没有有效的手机号可插入")
            return false

        cursor.executemany(insert_query, data_to_insert)
        connection.commit()
        print(f"成功插入 {len(data_to_insert)} 条数据")
        return true

    except exception as e:
        print(f"插入数据失败: {e}")
        if connection:
            connection.rollback()
        
        # 检查是否是唯一键冲突
        if "duplicate entry" in str(e):
            if url:  # 确保url有效
                update_is_deal(url, province, city)  # 执行额外逻辑
        
        return false
    
    finally:
        if cursor:
            cursor.close()
        if connection:
            connection.close()

3.3 关键优化点

4. java对比实现

在java中,mysql的duplicate entry错误通常对应sqlintegrityconstraintviolationexception,我们可以采用类似的优化策略。

4.1 java版本优化代码

import java.sql.*;
import java.util.list;

public class phonenumberdao {
    private static final string insert_query = 
        "insert into phone_numbers (prefix, suffix, phone_number, province, city) " +
        "values (?, ?, ?, ?, ?)";

    public boolean insertintomysql(list<string> phonenumbers, string prefix, 
                                  string province, string city, string url) {
        connection connection = null;
        preparedstatement statement = null;
        
        try {
            connection = databaseutil.getconnection(); // 获取数据库连接
            connection.setautocommit(false); // 开启事务
            
            statement = connection.preparestatement(insert_query);
            
            for (string phonenumber : phonenumbers) {
                if (phonenumber.length() == 11) {
                    string suffix = phonenumber.substring(7); // 后4位
                    statement.setstring(1, prefix);
                    statement.setstring(2, suffix);
                    statement.setstring(3, phonenumber);
                    statement.setstring(4, province);
                    statement.setstring(5, city);
                    statement.addbatch(); // 加入批处理
                }
            }
            
            statement.executebatch(); // 执行批处理
            connection.commit(); // 提交事务
            return true;
            
        } catch (sqlintegrityconstraintviolationexception e) {
            // 捕获唯一键冲突异常
            system.err.println("插入数据失败(唯一键冲突): " + e.getmessage());
            if (connection != null) {
                try {
                    connection.rollback(); // 回滚事务
                } catch (sqlexception ex) {
                    ex.printstacktrace();
                }
            }
            
            if (url != null) {
                updateisdeal(url, province, city); // 执行额外逻辑
            }
            return false;
            
        } catch (sqlexception e) {
            system.err.println("插入数据失败: " + e.getmessage());
            if (connection != null) {
                try {
                    connection.rollback();
                } catch (sqlexception ex) {
                    ex.printstacktrace();
                }
            }
            return false;
            
        } finally {
            // 关闭资源
            try {
                if (statement != null) statement.close();
                if (connection != null) connection.close();
            } catch (sqlexception e) {
                e.printstacktrace();
            }
        }
    }

    private void updateisdeal(string url, string province, string city) {
        // 实现更新逻辑
        system.out.println("检测到重复数据,更新状态: " + url);
    }
}

4.2 java优化点

  1. 精准捕获sqlintegrityconstraintviolationexception,而不是笼统的sqlexception
  2. 批处理优化:使用addbatch()executebatch()提高插入效率。
  3. 事务管理:显式控制commit()rollback(),确保数据一致性。

5. 总结与最佳实践

5.1 关键总结

优化点python 实现java 实现
异常捕获检查str(e)是否包含"duplicate entry"捕获sqlintegrityconstraintviolationexception
事务管理connection.rollback()connection.rollback()
资源释放finally块关闭连接finally块关闭资源
批处理优化cursor.executemany()addbatch() + executebatch()

5.2 最佳实践

  1. 精细化异常处理:不要仅捕获exception,而应根据业务需求区分不同错误类型。
  2. 事务安全:确保异常发生时能正确回滚,避免脏数据。
  3. 资源释放:使用try-finallytry-with-resources(java)确保数据库连接关闭。
  4. 日志记录:在异常处理时记录足够的信息,便于排查问题。

6. 扩展思考

  1. 是否应该先查询再插入?
    • 如果数据量较大,先查询再插入可能影响性能,直接捕获duplicate entry更高效。
  2. 如何优化update_is_deal逻辑?
    • 可以引入异步处理(如消息队列),避免影响主流程性能。
  3. 是否可以用insert ignoreon duplicate key update
    • 取决于业务需求,如果需要静默忽略重复数据,可以使用这些sql语法。

7. 结语

通过本文的优化案例,我们学习了如何在python和java中精细化处理mysql的duplicate entry错误,并执行额外的业务逻辑。关键在于:

到此这篇关于mysql处理重复数据插入的处理方案的文章就介绍到这了,更多相关mysql重复数据插入处理内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!

(0)

您想发表意见!!点此发布评论

推荐阅读

MySQL 分区与分库分表策略应用小结

04-14

MySQL高级查询之JOIN、子查询、窗口函数实际案例

04-14

一文带你搞懂MySQL中的隐式类型转换和显式类型转换

04-15

几种在Linux中找到MySQL的安装目录方法

04-15

MySQL下200GB大表备份的操作(利用传输表空间解决停服发版表备份问题)

04-15

深入理解Apache Kafka(分布式流处理平台)

04-15

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论