Index / Unique sulla colonna 'deleted_at'?

2

Abbiamo una tabella degli account in un DB Postgres che ha un indice univoco su user_id e product . Gli utenti possono avere molti account, non c'è una tabella di prodotti. Occasionalmente gli utenti creeranno un account accidentalmente e dovremo aggiungere quell'account al loro record User originale, dopo aver raccolto alcune informazioni su di esso che non possiamo semplicemente lanciare.

A causa dell'indice univoco su product e user_id , dobbiamo eseguire qualche serio collegamento / scollegamento sul record Account e registrare i dati da un record account in un campo JSONB sull'altro record prima di connetterti fino al corretto record User .

Abbiamo una colonna deleted_at nella tabella Account che viene utilizzata moderatamente e ho proposto di aggiungerla all'indice (user_id, product_id) . In questo modo, qualsiasi record che ha NULL deleted_at per un dato user_id, product_id è l'account "attivo" e gli account possono essere contrassegnati come deprecati / inattivi semplicemente impostando un deleted_at .

Ciò richiederebbe alcune riscritture nelle nostre ricerche, ma non sarebbero necessariamente estese, perché il nostro ORM fornisce una funzionalità di ambito che possiamo applicare a tutte le query.

Ho ottenuto un respingimento sull'idea, ma nulla ha riguardato l'impatto sulle prestazioni o gli inconvenienti tecnici, solo affermazioni sulla falsariga di "Le persone lo fanno davvero?" o "Non l'ho mai visto prima". Giuro che ho visto le aziende farlo, ma sarebbe difficile fornire prove.

Qualcuno può fornire una critica alle prestazioni o ai modelli di questo approccio? Qualcuno ha visto questo tipo di approccio? Se no, hai mai risolto questo tipo di problema?

    
posta kidCoder 06.12.2018 - 22:22
fonte

2 risposte

1

Il fatto che per un tipico indice B-tree probabilmente non sarà terribilmente utile e potenzialmente dannoso a causa della cardinalità estremamente bassa nella colonna deleted_at (può essere sempre vero o falso). Nella maggior parte dei casi non vorrai mai eseguire query su questa colonna e quasi sempre vorremmo filtrare i record laddove questo è vero (cancellato).

Una tabella partizionata è un buon approccio qui. È possibile suddividere la tabella sui valori validi di questa colonna in modo tale che i blocchi dei dati del tablespace siano organizzati in modo tale che i dati eliminati e non eliminati siano collocati insieme. Se ora esegui una query con un indice locale e filtri sulla colonna della partizione, eseguirai solo scansioni di indici o scansioni di tabelle nella partizione a cui sei interessato.

Questo ha l'ulteriore vantaggio che anche l'inserimento dei record è più veloce.

    
risposta data 07.12.2018 - 21:06
fonte
1

Stai giocando con l'idea di lavorare immutabilmente. Niente è mai distrutto. Devi solo cambiare le cose aggiungendo nuove cose. Questo approccio non distruttivo disorienta le persone abituate alla mentalità CRUD. Ma finché hai la capacità di archiviazione funziona. Basta guardare wikipedia. Cambia tutto il tempo e nulla è mai veramente perso.

Con questa implementazione ti imbatterai in un problema se permetti loro di contrassegnare un record come eliminato e quindi di crearne uno quasi identico quando hai dei vincoli di unicità sui campi. Dovrai decidere se vuoi impedirlo o in qualche modo legare l'unicità allo stato di cancellazione.

Come ogni modifica apportata a una tabella, devi essere sicuro che tutti gli usi di quella tabella vengano aggiornati quando apporti la modifica. Ma sì, puoi sicuramente smettere di cancellare i record solo perché alcuni utenti hanno sbagliato.

Ora, se un avvocato ti presenta un ordine del tribunale, è meglio che gli strumenti SQL siano a portata di mano.

    
risposta data 07.12.2018 - 20:56
fonte