当前位置: 首页 > 知识库问答 >
问题:

后端 - 如何在MySQL中高效处理多表插入操作?

鲜于宏义
2024-03-11

目前有个需求是要将csv文件内容分别插入到某数据库的两张表中,有一定依赖关系。由于一直是学生本科刚大四没毕业,故实战经验与性能优化经验薄弱

demo信息如下:

两张表分别是角色信息表和用户信息表

角色信息表

学号/工号 姓名 性别 角色(依赖权限表id) 科目表id(依赖于科目表)

用户信息表

uuid 手机号 密码 角色id(依赖于角色信息表)

权限表:老师、管理员、学生

科目表:语、数、英……

想请教各位大佬,用sql语句一次性批量插入与使用for循环去插入,性能方面影响大吗


注:数据库环境为MySQL

共有2个答案

南宫书
2024-03-11

会excel吗?也可以在excel中处理好数据,navicat直接导入excel。以【角色信息表】、【科目表】为例:
1)导入【科目表】数据
2)导出【科目表】数据为excel文件(包含科目表id),为E1
3)将【角色信息表】.csv文件转为excel,为E2。用excel的vlookup函数,将E2中的 科目表名称 替换为E1中的 科目表id
......
这个会替换操作之后,其他的也是替换为对应的id,然后再将整理好的excel导入

壤驷建德
2024-03-11

在MySQL中,一次性批量插入通常比循环插入性能更好。这是因为批量插入可以减少与数据库的交互次数,降低网络开销,并允许数据库更有效地处理数据。

对于你的情况,考虑到你有两张表,并且它们之间存在依赖关系,建议采取以下策略:

  1. 预处理CSV数据
* 首先,读取CSV文件,并将其内容解析为数据结构(如Python中的列表或字典)。* 确保数据的完整性和准确性,处理任何可能的错误或缺失值。
  1. 使用事务
* 开始一个事务,以确保数据的完整性。* 批量插入数据到角色信息表和用户信息表。
  1. 批量插入到角色信息表
* 对于角色信息表,可以一次性插入多条记录。例如,使用`INSERT INTO`语句,并列出所有要插入的记录。* 插入完成后,获取新插入的角色ID(如果是自增的,MySQL会自动分配)。
  1. 根据角色ID批量插入到用户信息表
* 使用上一步中获得的角色ID,为用户信息表中的每条记录设置`角色id`字段。* 同样,一次性插入多条记录到用户信息表。
  1. 提交事务
* 如果所有插入操作都成功,则提交事务。* 如果在插入过程中发生错误,可以回滚事务,以确保数据的一致性。

示例SQL语句(假设你使用的是Python):

import mysql.connector# 连接数据库cnx = mysql.connector.connect(user='your_username', password='your_password', host='your_host', database='your_database')cursor = cnx.cursor()# 预处理CSV数据# 假设 data 是一个包含所有数据的列表,每个元素是一个字典,表示一条记录# 开始事务cnx.start_transaction()try:    # 批量插入角色信息    query = "INSERT INTO 角色信息表 (学号/工号, 姓名, 性别, 角色, 科目表id) VALUES (%s, %s, %s, %s, %s)"    cursor.executemany(query, [(item['学号/工号'], item['姓名'], item['性别'], item['角色'], item['科目表id']) for item in data])    # 获取新插入的角色ID    cnx.commit()    cursor.execute("SELECT LAST_INSERT_ID()")    last_role_id = cursor.fetchone()[0]    # 批量插入用户信息    query = "INSERT INTO 用户信息表 (uuid, 手机号, 密码, 角色id) VALUES (%s, %s, %s, %s)"    cursor.executemany(query, [(item['uuid'], item['手机号'], item['密码'], last_role_id) for item in data])    # 提交事务    cnx.commit()except mysql.connector.Error as err:    # 发生错误时回滚事务    cnx.rollback()    print("Error:", err)finally:    cursor.close()    cnx.close()

注意:这只是一个基本示例,你可能需要根据你的具体需求和数据结构进行调整。

总的来说,使用批量插入而不是循环插入可以显著提高性能,特别是在处理大量数据时。但是,你也需要确保数据的一致性和完整性,这通常意味着使用事务来管理你的插入操作。

 类似资料:
  • 问题内容: 我知道MySQL中并发SELECT和INSERT存在一个问题。但是,我的问题是,如果我与MySQL建立两个连接并继续使用这两个连接来加载数据,MySQL是同时获取数据还是在加载另一个之前等待一个完成? 我想知道两种情况下MySQL的行为。就像当我尝试在打开单独的连接时尝试同时在同一张表或不同表中加载数据时一样。 问题答案: 如果要创建与数据库的新连接并从两个链接执行插入,那么从数据库的

  • 问题内容: 在一个表(jdbc / connector-mysql数据库)中插入1000行的最佳/最省时的方法是什么?(它是一个缓冲区,每次充满时都需要转储到数据库中) 1-一个自动生成/固定的SQL语句? 2 3-存储过程 4-通过文件批量插入数据? 5-(您的解决方案) 问题答案: LOAD DATA INFILE语句可能是提高性能的最佳选择。(来自上面的选项列表中的#4)尽管由于您需要创建中

  • 问题内容: 这个问题的答案是 社区的努力。编辑现有答案以改善此职位。它目前不接受新的答案或互动。 如果一次插入多行,数据库查询会更快吗: 喜欢 (我需要插入2-3000行) 问题答案: 使用语法的语句可以插入多行。为此,请包括多个列值列表,每个列值括在括号内并用逗号分隔。 例: 资源

  • 问题内容: 在MySQL中,我会使用 但这会导致SQLite错误。SQLite的正确语法是什么? 问题答案: 在此之前,已经回答了这一问题:是否可以一次在SQLite数据库中插入多行? 要回答您对OMG Ponies的评论,请回答: 从3.7.11版本开始,SQLite确实支持多行插入。理查德·希普(Richard Hipp)评论:

  • 问题内容: 通常,我可以在MySQL表中插入一行并取回。但是,现在,我想将许多行批量插入表中并获取ID数组。有人知道我该怎么做吗? 有一些类似的问题,但并不完全相同。我不想将新ID插入任何临时表;我只想找回ID数组。 我可以从批量插入中检索lastInsertId吗? 带有last_insert_id()的MySQL多行插入选择语句 问题答案: 旧线程,但只是研究了一下,所以去了:如果您在最新版本

  • 问题内容: 我有一个经常插入新数据的表。我需要获取表的最后一个ID。我怎样才能做到这一点? 类似于吗? 问题答案: 如果您使用的是PDO,请使用。 如果您使用的是Mysqli,请使用。 如果您仍在使用Mysql: 请不要在新代码中使用函数。它们不再维护,已正式弃用。看到 红色框了 吗?了解 准备的语句 来代替,并使用 PDO 或库MySQLi -本文将帮助你决定哪些。如果您选择PDO,这是一个很好