Suggerimenti dell'algoritmo per la gestione delle eliminazioni Soft CRUD per l'eliminazione e il ripristino con più modelli proprietari

1

Possiedo un ORM basato su record attivo con eliminazioni software (Laravel Eloquent specifico) in un database SQL.

Il comportamento "soft delete" integrato nell'ORM è: Se il record non viene cancellato, deleted_at è nullo. Quando un record viene eliminato, il campo deleted_at viene popolato con un timestamp.

L'ORM utilizza il campo 'deleted_at' internamente nella sua logica e crea il campo. È difficile modificare il tipo di deleted_at .

Ho la situazione in cui ho tre modelli (tabelle), A, B e C. Il modello C appartiene sia a A che a B. Neppure A o B appartengono l'uno all'altro. Quindi la tabella C contiene colonne per contenere chiavi esterne su A e B.

Affinché C sia valido, entrambi i suoi genitori non devono essere cancellati. Se A o B vengono cancellati, anche C deve essere cancellato.

Tuttavia, se A o B viene cancellato, quindi ripristinato (cioè% colonnadeleted_at impostato su null), allora anche C dovrebbe essere ripristinato.

Sto cercando di capire un algoritmo per determinare quando ripristinare C, se A e B sono ripristinati.

Mi sto appoggiando ad un algoritmo di conteggio dei riferimenti? Quindi, quando A o B viene eliminato, cancella C e incrementa il deleted_count di C. Se A o B viene ripristinato, allora decrementa C deleted_count e se deleted_count è 0, quindi ripristina C?

Questo suona come l'approccio migliore per questo tipo di situazione? Qualche ovvio inconveniente?

    
posta Josh Petitt 15.02.2017 - 23:02
fonte

1 risposta

1

Evita il conteggio dei riferimenti o altre soluzioni alternative. Ciò richiede la modifica manuale di C o l'aggiunta di trigger. La prima opzione è soggetta a errori, la seconda danneggia le prestazioni.

Poiché C ha chiavi esterne per A e B , basta aggiungere un campo "falso" alla query C : forse farlo attraverso una vista. Pseudocodice SQL di seguito:

CREATE VIEW c_view AS
SELECT C.*,
  (CASE WHEN A.deleted_at IS NOT NULL
         AND B.deleted_at IS NOT NULL
        THEN MAX(A.deleted_at, B.deleted_at)
        ELSE NULL
   END) AS deleted_at
FROM C
INNER JOIN A ON A.id = C.A_id
INNER JOIN B ON B.id = C.B_id

Solo per reiterare, questo è pseduo -SQL, non qualcosa che è garantito per essere sintassi corretta o testata. Si spera che illustri l'idea generale: non copiare i dati, cercarli direttamente quando si esegue una query su C . Se disponi di indici appropriati sulle chiavi primarie e esterne, dovrebbe essere velocissimo e non avere il rischio di registrare dati errati nel database.

    
risposta data 16.02.2017 - 00:03
fonte

Leggi altre domande sui tag