Domanda

OK, quindi praticamente ogni applicazione basata su database deve gestire "non attivo" record. O, soft-delezioni o contrassegnare qualcosa come "da ignorare". Sono curioso di sapere se ci sono pensieri alternativi radicali su una colonna "attiva" (o una colonna di stato).

Ad esempio, se avessi un elenco di persone

CREATE TABLE people (
  id       INTEGER PRIMARY KEY,
  name     VARCHAR(100),
  active   BOOLEAN,
  ...
);

Ciò significa che per ottenere un elenco di persone attive, è necessario utilizzare

SELECT * FROM people WHERE active=True;

Qualcuno suggerisce che i record non attivi vengano spostati su una tabella separata e dove viene fatto un UNION appropriato per unire i due?

Curiosità che colpisce ...

EDIT: dovrei chiarire, sto arrivando a questo da una prospettiva purista. Vedo come l'archiviazione dei dati potrebbe essere necessaria per grandi quantità di dati, ma non è da lì che provengo. Se fai un SELECT * FROM persone, sarebbe logico per me che quelle voci siano in un certo senso "attive"

Grazie

È stato utile?

Soluzione

Partizionate la tabella sul flag attivo, in modo che i record attivi siano in una partizione e i record inattivi siano nell'altra partizione. Quindi si crea una vista attiva per ogni tabella in cui è automaticamente presente il filtro attivo. Il motore di query del database limita automaticamente la query alla partizione in cui sono presenti i record attivi, che è molto più veloce rispetto all'utilizzo di un indice su tale flag.

Ecco un esempio di come creare una tabella partizionata in Oracle. Oracle non ha tipi di colonne booleane, quindi ho modificato la struttura della tabella per scopi Oracle.

CREATE TABLE people
(
   id       NUMBER(10),
   name     VARCHAR2(100),
   active   NUMBER(1)
)
PARTITION BY LIST(active)
(
   PARTITION active_records VALUES (0)
   PARTITION inactive_records VALUES (1)
);

Se lo desideri, puoi posizionare ogni partizione in diversi tablespace. Puoi anche partizionare anche i tuoi indici.

Per inciso, questa sembra una ripetizione di this domanda, in quanto neofita che devo porre, qual è la procedura per gestire i duplicati non intenzionali?

Modifica: come richiesto nei commenti, fornito un esempio per la creazione di una tabella partizionata in Oracle

Altri suggerimenti

Bene, per assicurarti di disegnare solo record attivi nella maggior parte delle situazioni, puoi creare viste che contengono solo i record attivi. In questo modo è molto più semplice non tralasciare la parte attiva.

Usiamo un enum ('ACTIVE', 'INACTIVE', 'DELETED') nella maggior parte delle tabelle, quindi in realtà abbiamo un flag a 3 vie. Trovo che funzioni bene per noi in diverse situazioni. Il chilometraggio può variare.

Spostare cose inattive è di solito un'idea stupida. È un sacco di sovraccarico con un sacco di potenziale per i bug, tutto diventa più complicato, come l'archiviazione del materiale ecc. Cosa fai con i dati correlati? Se si sposta anche tutto ciò, è necessario modificare ogni singola query. Se non lo sposti, quale vantaggio speravi di ottenere?

Questo porta al punto successivo: PERCHÉ vorresti spostarlo? Una tabella correttamente indicizzata richiede una ricerca aggiuntiva quando la dimensione raddoppia. Qualsiasi miglioramento delle prestazioni è destinato a essere trascurabile. E perché dovresti anche pensarci fino al lontano futuro futuro in cui hai effettivamente problemi di prestazioni?

Penso che guardandolo rigorosamente come un pezzo di dati, il modo in cui viene mostrato nel post originale è corretto. Il dato di flag attivo dipende direttamente dalla chiave primaria e dovrebbe trovarsi nella tabella.

La tabella contiene dati sulle persone, indipendentemente dallo stato corrente dei loro dati.

La bandiera attiva è in qualche modo brutta, ma è semplice e funziona bene.

Potresti spostarli in un'altra tabella come suggerito. Suggerirei di guardare la percentuale di record attivi / inattivi. Se hai oltre il 20 o il 30% di record inattivi, potresti considerare di spostarli altrove. Altrimenti, non è un grosso problema.

Sì, lo faremmo. Al momento abbiamo " active = 'T / F' " colonna in molte delle nostre tabelle, principalmente per mostrare la riga "più recente". Quando viene inserita una nuova riga, la precedente riga T viene contrassegnata con F per tenerla a fini di controllo.

Ora stiamo passando a un approccio a 2 tabelle, quando viene inserita una nuova riga, la riga precedente viene spostata in una tabella della cronologia. Questo ci offre prestazioni migliori per la maggior parte dei casi, guardando i dati attuali.

Il costo è leggermente superiore al vecchio metodo, prima dovevi aggiornare e inserire, ora devi inserire e aggiornare (cioè invece di inserire una nuova riga T, modifichi la riga esistente con tutti i nuovi dati), quindi il costo è solo quello di passare un'intera riga di dati invece di passare solo le modifiche. Difficilmente ciò avrà alcun effetto.

Il vantaggio in termini di prestazioni è che l'indice della tabella principale è significativamente più piccolo e puoi ottimizzare meglio i tuoi tablespace (non cresceranno così tanto!)

I flag binari come questo nel tuo schema sono un'idea MALE. Considera la query

SELECT count(*) FROM users WHERE active=1

Sembra abbastanza semplice. Ma cosa succede quando hai un gran numero di utenti, così tanti che sarebbe necessario aggiungere un indice a questa tabella. Ancora una volta, sembra semplice

ALTER TABLE users ADD INDEX index_users_on_active (active)

SALVO !! Questo indice è inutile perché la cardinalità su questa colonna è esattamente due! Qualsiasi ottimizzatore di query del database ignorerà questo indice a causa della sua bassa cardinalità e eseguirà una scansione della tabella.

Prima di riempire il tuo schema con utili flag, considera come accederai a quei dati.

https://stackoverflow.com/questions/108503/mysql-advisable-number -di-righe

Utilizziamo flag attivi abbastanza spesso. Se il tuo database sarà molto grande, potrei vedere il valore della migrazione di valori inattivi in ??una tabella separata.

Avresti quindi bisogno di unire le tabelle solo quando qualcuno vuole vedere tutti i record, attivi o inattivi.

Nella maggior parte dei casi è sufficiente un campo binario che indica l'eliminazione. Spesso esiste un meccanismo di pulizia che rimuove quei record eliminati dopo un certo periodo di tempo, quindi potresti voler avviare lo schema con un timestamp eliminato.

Il passaggio a una tabella separata e il loro backup richiede tempo. A seconda del numero di record non in linea e della frequenza con cui è necessario ripristinarli, potrebbe essere o non essere una buona idea.

Se la maggior parte non ritorna dopo essere stata sepolta e viene utilizzata solo per riepiloghi / rapporti / qualunque cosa, allora renderà la tua tabella principale più piccola, le query più semplici e probabilmente più veloci.

Utilizziamo entrambi i metodi per gestire i record inattivi. Il metodo che utilizziamo dipende dalla situazione. Per i record che sono essenzialmente valori di ricerca, utilizziamo il campo Bit attivo. Questo ci consente di disattivare le voci in modo che non vengano utilizzate, ma ci consente anche di mantenere l'integrità dei dati con le relazioni.

Usiamo " sposta nella tabella di separazione " metodo in cui i dati non sono più necessari e i dati non fanno parte di una relazione.

La situazione determina davvero la soluzione, pensa:

Se la tabella contiene utenti, diversi "flag" campi potrebbero essere utilizzati. Uno per Eliminato, Disabilitato ecc. O se lo spazio è un problema, allora sarebbe sufficiente un flag per disabilitato, e quindi effettivamente cancellare la riga se sono stati eliminati.

Dipende anche dalle politiche per l'archiviazione dei dati. Se esistono criteri per conservare i dati archiviati, molto probabilmente sarebbe necessaria una tabella separata dopo un lungo periodo di tempo.

No - questa è una cosa abbastanza comune - un paio di variazioni a seconda dei requisiti specifici (ma le hai già coperte):

1) Se si prevede di avere un intero MAZZO di dati, come più terabyte o più, non è una cattiva idea archiviare immediatamente i record eliminati, anche se è possibile utilizzare un approccio combinato di marcatura come eliminata e copia in tabelle di archivio.

/ p>

2) Ovviamente esiste ancora l'opzione di cancellare un record - sebbene noi sviluppatori tendiamo ad essere dei pacchetti di dati - suggerisco che dovresti esaminare il processo aziendale e decidere se ora c'è bisogno di mantenere il dati - se esiste - fallo ... se non c'è - probabilmente dovresti sentirti libero solo di buttare via la roba ..... di nuovo, secondo lo specifico scenario aziendale.

Da una "prospettiva purista" il modello realzionale non fa distinzione tra una vista e una tabella - entrambe sono relazioni. Pertanto, l'uso di una vista che utilizza il discriminatore è perfettamente significativo e valido a condizione che le entità siano denominate correttamente, ad es. Persona / ActivePerson.

Inoltre, da una "prospettiva purista", la tabella dovrebbe essere denominata persona, non persone poiché il nome della relazione riflette una tupla, non l'intero insieme.

Per quanto riguarda l'indicizzazione del valore booleano, perché no:

ALTER TABLE users ADD INDEX index_users_on_active (id, active) ;  

Non migliorerebbe la ricerca?
Tuttavia non so quanto di tale risposta dipenda dalla piattaforma.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top