MySQL 实现 插入或更新操作

实现方法:ON DUPLICATE KEY UPDATE

  1. 用户数据同步
    • 在用户数据同步的场景中,如果用户已经存在,则直接更新其数据;如果用户不存在,则插入新的记录。ON DUPLICATE KEY UPDATE可以在一次操作中完成这个任务,而无需先查询再决定是插入还是更新。
  2. 批量数据导入
    • 在导入大量数据时,如果数据中可能存在重复的主键或唯一索引,使用ON DUPLICATE KEY UPDATE可以确保数据的一致性。它会根据唯一索引判断记录是否重复,如果重复则更新,如果不重复则插入。
  3. 计数器或统计字段的更新
    • 在某些场景中,可能需要更新表中的计数器或统计字段。例如,当有一个记录表示某个事件的次数时,如果事件再次发生,可以使用ON DUPLICATE KEY UPDATE来增加这个计数器的值。
  4. 避免并发冲突
    • 在高并发环境下,先查询后更新可能会遇到“丢失更新”的问题。而ON DUPLICATE KEY UPDATE通过数据库的内置机制处理冲突,有助于减少这类并发问题。

SQL具体实现

条件:必须包含主键

INSERT INTO scientists (`index`,Name,Born,Died,Age,Occupation)
	-- 基础的 INSERT 使用,必须包含主键
    select `index`,Name,Born,Died,Age,Occupation
    from app_go
    ON DUPLICATE KEY UPDATE
    -- 需要更新的字段
    Born = values(Born),
    Died = values(Died),
    Age  = values(Age),
    Occupation = values(Occupation);

更多案例:

CREATE TABLE `users` (  
  `id` varchar(36) NOT NULL,  
  `username` varchar(25) NOT NULL,  
  `email` varchar(255) DEFAULT NULL,  
  PRIMARY KEY (`id`),  
  UNIQUE KEY `username` (`username`)  
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;  
  
-- 插入新用户  
INSERT INTO users(id, username, email) VALUES('1', 'user1', 'user1@example.com')  
ON DUPLICATE KEY UPDATE email='user1_updated@example.com';  
  
-- 更新已存在用户的email  
INSERT INTO users(id, username, email) VALUES('1', 'user1', 'user1_new@example.com')  
ON DUPLICATE KEY UPDATE email='user1_new_updated@example.com';

-- 在上面的示例中,如果id或username已经存在于表中,则执行UPDATE操作,更新email字段的值。如果不存在,则执行INSERT操作,插入新的记录。

使用Python连接MySQL数据库并运用语法

# 使用Python连接Mysql数据库并运用语法  
  
# 导入模块  
from sqlalchemy import create_engine, text  
import pandas as pd  
  
# 设置连接数据库(请根据实际情况修改连接字符串)  
engine = create_engine('mysql+pymysql://root:root@localhost:3306/user_db?charset=utf8mb4')  
  
# 编辑SQL语句  
sql = """  
    INSERT INTO scientists (id, Name, Born, Died, Age, Occupation)  
    SELECT id, Name, Born, Died, Age, Occupation  
    FROM app_go  
    ON DUPLICATE KEY UPDATE  
    Born = VALUES(Born),  
    Died = VALUES(Died),  
    Age = VALUES(Age),  
    Occupation = VALUES(Occupation);  
"""  
  
try:  
    # 运用with 可以自动关闭游标和连接 释放内存  
    with engine.connect() as conn:  
        with engine.begin() as trans:  
            trans.execute(text(sql))  
            print("数据插入/更新成功")  
except Exception as e:  
    print(f"发生错误:{e}")  
  
# 读取SQL数据  
try:  
    df = pd.read_sql('SELECT * FROM scientists', engine)  
    print(df.head())  # 打印前几行数据作为示例  
except Exception as e:  
    print(f"读取数据发生错误:{e}")