2014-10-17 16 views
6

Chciałbym wdrożyć usuwanie logiczne dla rekordu kanału informacyjnego, aby obsługiwać późniejsze cofanie.
System jest w produkcji, więc każde rozwiązanie powinno obsługiwać istniejące dane.
Wstawianie rekordów do kanału jest idempotentne, dlatego wstawienie już usuniętego rekordu (ma ten sam klucz podstawowy) nie powinno go cofnąć.
Każde rozwiązanie powinno obsługiwać zapytania w celu pobrania strony istniejących lub usuniętych rekordów.Obsługa usuwania logicznego dla istniejącej tabeli plików danych

tabela pasza:

CREATE TABLE my_feed (
    tenant_id int, 
    item_id int, 
    created_at timestamp, 
    feed_data text, 
PRIMARY KEY (tenant_id, created_at, feed_id)) 
WITH compression = { 'sstable_compression' : 'LZ4Compressor' } 
AND CLUSTERING ORDER BY (created_at DESC); 

Istnieją dwa podejścia myślałem o ale obie mają poważne wady:
1. Przenieś usunięte rekordy do innej tabeli. Zapytania są trywialne i migracja nie jest wymagana, ale idempotentne wstawki wydają się być trudne (czytać tylko przed wstawieniem?).
2. Dodaj kolumnę is_deleted. Utwórz dodatkowy indeks dla tej kolumny, aby obsługiwać zapytania. Idempotent inserts wydaje się łatwiejszy w obsłudze (transakcje lekkie lub trik aktualizacji). Główną wadą jest to, że starsze rekordy mają wartość zerową, a zatem wymagają migracji danych.

Czy istnieje trzecie bardziej eleganckie podejście? Czy popierasz jedną z powyższych sugestii?

Odpowiedz

1

Jeśli prowadzisz osobną tabelę dla usuniętych rekordów, możesz użyć konstrukcji CQL o numerze BATCH do wykonania operacji "przenieś", ale ponieważ jedyny zapis usunięcia znajduje się w tej tabeli, musisz ją najpierw sprawdzić, jeśli chcesz zachować opisałeś, że nie chcesz ponownie animować usuniętych rekordów. Czytając przed piśmie jest zwykle anty-wzór, itp

stosując kolumnę is_deletedmoże wymaga trochę pracy migracji, jak wspomniałeś, ale potencjalnie bardziej poważnym problemem może być to, że tworzenie indeksu na bardzo niski - kolumna kardynalności jest zwykle niezwykle nieefektywna. W przypadku pola boolean myślę, że indeks zawierałby tylko dwa wiersze. Jeśli nie usuniesz zbyt często, oznacza to, że twój "fałszywy" wiersz będzie bardzo szeroki, a zatem almost useless.

Jeśli uniknąć tworzenia indeksu wtórnego dla kolumny is_deleted i pozwolić zarówno null i false wskazać aktywne rekordy, a jedynie wyraźny true wskazuje usunięte z nich, może nie trzeba migrować czegokolwiek. (Czy rzeczywiście wiesz, jakie istniejące rekordy usunąć podczas migracji?) Następnie pozostawiłbyś filtrowanie usuniętych rekordów klientowi, który prawdopodobnie będzie już odpowiedzialny za niektóre z twoich zachowań stronicowania. Wadą tego projektu jest to, że możesz poprosić o> N rekordów, aby uzyskać N, które nie zostały usunięte!

Mam nadzieję, że pomogę i odpowiem na pytanie, tak jak je określiłeś. Byłbym ciekawy, dlaczego musiałbyś się wystrzegać, aby już usunięte rekordy zostały przywrócone do życia, ale mogę sobie wyobrazić sytuację, w której masz wielu aktorów pracujących nad danym plikiem danych (i problemami CAS, które mogą powstać).

W nieco niezwiązanej uwadze możesz rozważyć użycie timeuuid zamiast timestamp dla swojego pola created_at. CQL obsługuje funkcję dateOf(), aby pobrać tę datę, jeśli jest to przeszkodą. (Może być również niemożliwe zderzenie się z partycjami tenant_id, w takim przypadku możesz mnie bezpiecznie zignorować.)

+0

Muszę chronić się przed przywróceniem już usuniętych rekordów, ponieważ system zaprojektowano tak, aby jeden rekord mógł być wysłany więcej niż jeden raz (próby, migracje, procesy samoleczenia). W takich przypadkach oczekuje się, że po wstawieniu rekordu nie zostanie zmieniony, chyba że użytkownik go usunie. –

+1

O 'is_deleted': zakładając, że klucz partycji (tenant_id) jest zawsze określony w zapytaniu, indeks wtórny powinien być efektywny również dla pól o niskiej liczności: [http://stackoverflow.com/q/26439396/3950710] –

Powiązane problemy