Я не могу говорить за MySQL, но PostgreSQL имеет транзакционный DDL. Это замечательная функция, и это означает, что ваш второй вариант, загружая новые данные в фиктивную таблицу и затем выполняющий переименование таблицы, должен работать отлично. Если вы хотите заменить таблицу foo
на foo_new
, вам нужно только загрузить новые данные в foo_new
и запустить скрипт для переименования. Этот сценарий должен выполняться в своей собственной транзакции, поэтому, если что-то не так с переименованием, и foo
, и foo_new
останутся нетронутыми при откате.
Основная проблема этого подхода заключается в том, что он может немного запутаться, обрабатывая внешние ключи из других таблиц, которые вводят foo
. Но, по крайней мере, вы гарантировано, что ваши данные останутся непротиворечивыми.
Лучшим подходом в долгосрочной перспективе, я думаю, является просто непосредственное обновление данных (ваш первый вариант). Еще раз, вы можете закрепить все обновления в одной транзакции, так что вам гарантирована семантика "все или ничего". Еще лучше было бы онлайн обновления, просто обновляя данные непосредственно, когда новая информация становится доступной. Это может не подойти вам, если вам нужны результаты чьей-либо пакетной работы, но если вы можете это сделать, это лучший вариант.