mysql - 使用唯一列执行 SQL 批量插入/更新时保持数据完整性和一致性

标签 mysql sql performance validation transactions

我有一个 Excel 文件,其中包含下载时数据库中的内容。每行都使用名为 id_number 的标识符进行标识。用户可以使用新的唯一 id_number 在文件中添加新行。上传后,对于每个 Excel 行,

  • 当数据库中存在 id_number 时,将对数据库行执行更新。
  • 当数据库中不存在 id_number 时,将对数据库行执行插入操作。

除了 Excel 文件之外,还可以使用名为 report.php 的文件单独添加或更新数据。例如,如果用户只想为员工添加一项数据,则可以使用此页面。

理想情况下,我想在重复键更新上执行插入...以获得最大性能。我也可能将它们全部放入交易中。但是,我认为整个过程存在一些缺陷:

  • 在任何添加/更新之前,必须根据相应的数据库行对所有 Excel 行进行验证检查。原因是因为表中有许多唯一的列。这就是为什么我必须执行一些选择语句以确保在执行任何添加/更新之前数据有效。这对于 500 行 69 列的表有效吗?我可能可以获取所有数据并将所有数据存储在 php 数组中,并对数组进行验证检查,但是如果有人通过 report.php 添加新行(id_number 为 5)会发生什么?那么假设我上传的excel文件中也包含一行id_number为5的行呢?这可能会破坏我的验证,因为如果不执行大量 select 语句,我无法确定我的数据是最新的。
  • 假设系统正在添加/更新从 Excel 文件检索的数据的事务中,则来自 report.php 的人员会添加一行,因为所有验证均已满足(例如,没有重复的 id_numbers)。假设此时要从 Excel 文件添加的下一行和用户将在 report.php 上添加的行具有相同的 id_number。然后会发生什么?我对事务没有太多了解,我认为它们至少可以防止两个查询同时更改一行?这是正确的吗?

我不太介意这种情况。但有些文件有很多行,处理所有行可能需要很长时间。

我想到的解决此问题的一种方法是:在处理 Excel 文件上传时,我必须阻止用户使用 report.php 修改 Excel 文件当前保存的行。这样可以吗?

解决这些问题的最佳方法是什么?我正在使用mysql。

最佳答案

如果您确实需要允许用户生成自己的唯一 ID,那么您可以在进行验证和插入时锁定相关表。

如果您获得写锁,那么您可以确定在执行验证和插入工作时表不会更改。

`mysql> LOCK TABLES tbl_name WRITE`

别忘了

`mysql> UNLOCK TABLES;`

锁定的缺点是显而易见的,表被锁定。如果流量很高,那么所有流量都在等待,这可能会导致各种痛苦,(mysql 连接耗尽,这是一种常见的情况)

也就是说,我建议采用不同的路径,让 mysql 成为唯一生成唯一 id 的路径。也就是说,确保数据库表具有 auto_increment 唯一 id(主键),然后在电子表格中输入新记录,而无需给出唯一 id。然后mysql将确保新记录获得唯一的id,并且您不必担心锁定并且可以验证和插入而不用担心冲突。

关于500条记录69列表的性能问题,我只能说,如果php服务器和mysql服务器大小合理并且列不是大数据类型,那么这个数据量应该是可以在几分之一秒内轻松处理。也就是说,一行错误的代码可能会破坏性能,因此如果您的代码执行速度很慢,我会将其视为一个单独的优化问题。

关于mysql - 使用唯一列执行 SQL 批量插入/更新时保持数据完整性和一致性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46557170/

相关文章:

python - LOAD XML INFILE 将嵌套子项保存为普通文件

MySQl - 通过计算其他表中的数据来更新字段

php - 如何获得 Asterisk 通话指标?

php - 在 PHP 循环中插入数据时优化 PDO 函数

c# - 使用 linq 从动态 sql 查询中检索和打印数据

sql - 从返回引用游标记录的函数中获取

java - Spring - 添加一个低优先级的多线程服务(不影响生产性能)

performance - React Redux 中 `Provider` 和 `connect` 之间的区别

截断时的 SQL 触发器

android - 提高 Android ViewPager 性能