Utilizzo di una singola tabella per identità e metadati

2

Sono nella fase di progettazione iniziale di un progetto per fornire una piattaforma di e-commerce che richiederà la modellazione di diverse entità, prodotti, clienti, ordini, pagine CMS, ecc. Avranno tutti in comune alcune cose (ID, timestamp di creazione, timestamp dell'ultima modifica, ecc.).

Il mio primo pensiero è stato il solito di dare alle varie tabelle una colonna ID che utilizzerà il meccanismo del database per assegnare univocità (autoincrement in MySQL, sequenze in Postgres, ecc.) ma dato che hanno alcune cose in comune che stavo considerando un progetto in cui tutti i dati vengono mantenuti in una tabella BusinessObject di base e le tabelle per le altre entità utilizzano una chiave esterna primaria che fa riferimento alla tabella BusinessObject.

Ad esempio (in pseudocodice)

CREATE TABLE BusinessObject (
    id,
    date_created, 
    date_updated, 
    is_deleted,
    // etc
    PRIMARY KEY id AUTOINCREMENT
);

CREATE TABLE Customer (
    id,
    forename,
    surname,
    // etc
    PRIMARY KEY id
    FOREIGN KEY id REFERENCES BusinessObject.id
);

CREATE TABLE Product (
    id,
    name,
    price,
    description,
    // etc
    PRIMARY KEY id
    FOREIGN KEY id REFERENCES BusinessObject.id
);

e così via.

Posso pensare a una serie di vantaggi per questo approccio. Innanzitutto, un ID particolare esegue sempre il mapping solo su un particolare oggetto. Ad esempio, l'id 3 in un sistema in cui ogni tabella genera i propri ID potrebbe fare riferimento a un cliente, un ordine o qualsiasi altra cosa, mentre nel disegno sopra riportato, l'ID 3 sarà sempre un ordine, perché non potrebbe mai essere un cliente o prodotto con ID 3. Ciò renderebbe molto più semplice estrapolare l'oggetto business di riferimento dall'URL, consentendo un routing più semplice nel livello dell'applicazione.

Tuttavia, significa anche che ogni tabella del sistema deve unirsi alla tabella BusinessObject e sono preoccupato che ciò possa causare alcuni inconvenienti significativi. Ad esempio, il fatto che una determinata tabella sarà coinvolta in quasi tutte le query potrebbe comportare prestazioni ridotte per quella tabella o che potrebbe essere possibile che una riga in Customer faccia riferimento alla stessa riga in BusinessObject come una riga in Product, con conseguente perdita di integrità dei dati a meno che non vengano prese alcune misure aggiuntive per impedirlo.

Quindi, in sostanza, quali sono i pro e i contro di un design in cui una singola tabella fornisce i dati di identità per la maggior parte del resto del database? Tali progetti sono abbastanza comuni o è meglio avere solo una tabella con una propria identità e fare affidamento su una logica di applicazione più intelligente per determinare l'oggetto a cui si fa riferimento?

    
posta GordonM 01.03.2014 - 12:17
fonte

1 risposta

2

Stai progettando il tuo sistema nell'ordine errato. Devi prima sviluppare i tuoi oggetti di business. So che stai sviluppando il tuo DB innanzitutto perché stai tentando di imporre dei pattern su di esso che appartengono ai tuoi oggetti di business.

Stai anche commettendo l'errore comune di pensare che possa esserci un solo ID perché stai pensando in termini di chiavi primarie.

Inoltre, non è chiaro per me che quelle cose siano correlate come pensi che siano.

Supponendo che siano uno schema correlato, è necessario definire le interfacce per esprimere ciò, IHasBusinessEntityId, ICreatedDate, IModifiedDate. Si prega di non dimenticare il principio di segregazione dell'interfaccia. Allora forse puoi aggregare queste interfacce in un'interfaccia IAuditable?

Esplora prima gli schemi nei tuoi oggetti di business, quindi puoi concentrarti sul rendere la struttura del tuo tavolo veloce ed efficiente.

Ciascuna delle tue tabelle può avere BusinessEntityId (forse un guid, forse interi creati da un SEQUENCE), poi in aggiunta, le singole tabelle identificative int in sequenza da utilizzare come indice cluster (i guids non sono grandi per gli indici cluster). È quindi possibile utilizzare un UNION SQL per riportare tutti gli oggetti IAuditable da tabelle diverse.

Consiglio vivamente di non sposare tutti questi elementi in una sola tabella, poiché ti costerà problemi di flessibilità e prestazioni.

Questo approccio determinerà la frammentazione dell'indice cluster, che può drasticamente rallentare le query.

    
risposta data 11.04.2017 - 21:46
fonte

Leggi altre domande sui tag