Chcę zastąpić całą zawartość tabeli, nie wpływając na żadne przychodzące SELECT
instrukcje podczas procesu.
Przypadkiem użycia jest posiadanie tabeli, która przechowuje informacje o skrzynce pocztowej, które są regularnie wyodrębniane i muszą być przechowywane w tabeli PostgreSQL. Jest wielu klientów korzystających z aplikacji, która stale odpytuje tę samą tabelę.
Normalnie zrobiłbym coś takiego (przychodzący pseudokod) ...
BEGIN TRANSACTION
TRUNCATE TABLE
INSERT INTO
COMMIT
Niestety nie można odczytać tabeli podczas tego procesu; ze względu na czas potrzebny INSERT INTO
do ukończenia. Stół jest zamknięty.
W MySQL użyłbym ich RENAME TABLE
polecenia atomowego, aby uniknąć tych problemów ...
CREATE TABLE table_new LIKE table;
INSERT INTO table_new;
RENAME TABLE table TO table_old, table_new TO table; *atomic operation*
DROP TABLE table_old;
Jak mogę to osiągnąć w PostgreSQL?
Na potrzeby tego pytania możesz założyć, że nie używam kluczy obcych.
TRUNCATE
polecenie uzyska blokadę AccessExclusive na stole, więc nikt inny nie będzie mógł odczytać z tabeli, dopóki transakcja nie zostanie zatwierdzona lub wycofana.
delete
zamiast tego truncate
, będzie wolniejszy, ale bez blokowania czytników. Ile wierszy musisz usunąć?
DELETE
i INSERT
byłby zdecydowanie za długi.