Wydaje się dziwne, że muszę ręcznie wykonać SQL, aby użyć polecenia TRUNCATE. Czy jest w tym coś złego, przed czym chroni mnie DHH?
Odpowiedzi:
10 dla odpowiedzi № 1Za pomocą TRUNCATE
w niektórych bazach danych nie uruchamia wyzwalaczy. Za pomocą DELETE
dla każdego wiersza nadal będą uruchamiane wyzwalacze. TRUNCATE
również nie można go wycofać, więc jeśli zrobiłeś .destroy_all
w transakcji spowoduje to usunięcie wszystkich danych, nawet jeśli spróbujesz wycofać.
Tak, jesteś chroniony przed skutkami obcięcia.
3 dla odpowiedzi № 2
Zakładając, że używasz MySQL lub Postgre, a nie SQlite3 (który nie obsługuje TRUNCATE
), możesz dodać następującą metodę do swojego modelu.
def self.truncate
self.connection_pool.with_connection { |c| c.truncate(table_name) }
end
Zauważ, że nie wywołałoby to ActiveRecordoddzwanianie. Są lepsze sposoby na to, aby nie wiązać kodu z konkretną implementacją DB, ale nawet to jest lepsze niż samodzielne pisanie SQL.
1 dla odpowiedzi nr 3
Istnieje wiele przypadków użycia dla TRUNCATE
i moim zdaniem podane tutaj odpowiedzi są bardzo niewystarczające. Na przykładzie Postgres:
TRUNCATE
jest zdecydowanie bezpieczny dla transakcji w niektórych RDBMS, jak już zauważyli jsears. Można go wycofać, przynajmniej w Postgres. Czy szyny nie powinny być db-agnostyczne i pozwalają na takie rzeczy?TRUNCATE
wykona równieżBEFORE TRUNCATE
lubAFTER TRUNCATE
wyzwalacze w Postgresie. Jeśli spodziewasz sięDELETE
uruchomić spustTRUNCATE
to twoja wina projektowa!TRUNCATE
działa znacznie szybciej niżDELETE
szczególnie w przypadku dużych zestawów danych, ponieważ jest to pojedyncza krótka instrukcja DDL.- W architekturze MVCC w Postgres,
TRUNCATE
usuwa wszystkie wzdęcia indeksu i tabeli.
Z tych powodów jest dla mnie szalone, że Rails nie obsługuje TRUNCATE
. Nie, nie sądzę, aby podane powody były dobre.
-3 dla odpowiedzi № 4
Spójrz na Model.destroy_all i aktywny rekord: zależny =>: zniszcz relacje. Jeśli nie określisz: zależne =>: destory, niektóre z wartości domyślnych to ustawienie relacji na zero, ale nie zniszczenie rekordu.