【问题标题】:How to replace whole SQL table data frequently?如何频繁替换整个 SQL 表数据?
【发布时间】:2020-07-29 13:34:16
【问题描述】:

我有一个运行 cron 的 Spring 应用程序。 cron 每隔几分钟就会从外部 API 获取新数据。数据应该存储在数据库(MySQL)中,代替旧数据(旧数据应该被新数据覆盖)。 数据需要被覆盖而不是更新。应用程序本身提供 REST API,因此客户端能够从数据库中获取数据。因此,不应该出现客户端因为有数据更新而看到数据库中的空数据或仅部分数据的情况。 目前我已经尝试删除整个旧数据并插入新数据,但是有一个地方客户端只获取了一部分数据。我已经通过 Spring Data deleteAll 和 saveAll 方法进行了尝试。

@Override
@Transactional
public List<Country> overrideAll(@NonNull Iterable<Country> countries) {
    removeAllAndFlush();

    List<CountryEntity> countriesToCreate = stream(countries.spliterator(), false)
            .map(CountryEntity::from)
            .collect(toList());

    List<CountryEntity> createdCountries = repository.saveAll(countriesToCreate);

    return createdCountries.stream()
            .map(CountryEntity::toCountry)
            .collect(toList());
}

private void removeAllAndFlush() {
    repository.deleteAll();
    repository.flush();
}

我还考虑过有一个临时表来获取新数据,当数据完成时,只需将主表替换为临时表。这是个好主意吗?还有其他想法吗?

【问题讨论】:

  • 或者在两个孪生表之间交替切换可能使用 SQL 视图。
  • 是的,您可以将数据加载到另一个表中。然后将旧表重命名为其他表并将新表重命名为正在使用的表。
  • 数据需要被覆盖而不是更新。 REPLACE Statement 这样做。而且我建议您将新数据保存到临时表中,然后通过一个查询替换数据 - 这足够快,并且可以避免 客户端看到空数据或只是一部分数据的情况
  • 数据应该存储在数据库(MySQL)中,代替旧数据(旧数据应该被新数据覆盖)。 必须删除整个旧数据而是存储新数据?还是只有通过某些条件(例如某些 GUID)与新数据匹配的旧数据中的行必须被覆盖?
  • 必须删除整个旧数据

标签: java mysql sql spring


【解决方案1】:

这是个好主意。您可以通过在另一个表上工作直到它准备好然后通过重命名快速切换表来最大限度地减少停机时间。这也将提高用户的感知性能,因为不需要像使用 UPDATE/DELETE 时那样锁定记录。

在 MySQL 中,如果表上没有触发器,则可以使用 RENAME TABLE。它允许一次重命名多个表并且它以原子方式工作(即事务 - 如果发生任何错误,则不会进行任何更改)。您可以使用以下示例

RENAME TABLE countries TO countries_old, countries_new TO countries;
DROP TABLE countries_old; 

更多详情请参考这里

https://dev.mysql.com/doc/refman/5.7/en/rename-table.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-18
    • 1970-01-01
    • 2012-03-14
    相关资源
    最近更新 更多