Diciamo che l'entità del prodotto del negozio, ha caratteristiche comuni, come nome, descrizione, immagine, prezzo, ecc., Che prendono parte alla logica in molti luoghi e ha caratteristiche (semi) uniche, come l'orologio e il pallone da spiaggia sarebbero descritti da aspetti completamente diversi . Quindi penso che EAV si adatterebbe per archiviare quelle (semi) caratteristiche uniche?
L'uso di una struttura EAV ha diverse implicazioni che sono compromessi.
Stai negoziando uno "spazio minore per la riga perché non hai 100 colonne che sono null
" contro "query e modello più complessi".
Avere un EAV in genere significa che il valore è una stringa in cui è possibile inserire qualsiasi dato. Ciò ha quindi implicazioni sulla validità e sul controllo dei vincoli. Considera la situazione in cui hai inserito il numero di batterie utilizzate come qualcosa nella tabella EAV. Vuoi trovare una torcia che utilizza batterie di dimensioni C, ma meno di 4.
select P.sku
from
products P
attrib Ab on (P.sku = Ab.sku and Ab.key = "batteries")
attrib Ac on (P.sku = Ac.sku and Ac.key = "count")
where
cast(Ac.value as int) < 4
and Ab.value = 'C'
...
La cosa da capire qui è che non è possibile utilizzare un indice ragionevolmente sul valore. Inoltre, non puoi impedire a qualcuno di inserire qualcosa che non è un numero intero lì, o un numero intero non valido (usa batterie "-1") perché la colonna del valore viene utilizzata più volte per scopi diversi.
Ciò ha quindi implicazioni nel tentativo di scrivere un modello per il prodotto. Avrai dei simpatici valori digitati ... ma avrai anche Map<String,String>
solo una seduta lì con tutti i tipi di cose . Ciò ha quindi ulteriori implicazioni nel serializzarlo su XML o Json e la complessità del tentativo di eseguire convalide o query su tali strutture.
Alcune alternative o modifiche al modello da considerare sono invece di una chiave di formato libero, per avere un'altra tabella con chiavi valide. Significa invece di fare confronti di stringhe nel database, si sta verificando l'uguaglianza degli ID di chiave esterna. La modifica della chiave stessa viene eseguita in un punto. Hai un set di chiavi noto, il che significa che possono essere fatte come enum.
Potresti anche avere tabelle correlate che contengono attributi di una specifica classe di prodotto. Un reparto alimentari potrebbe avere un'altra tabella a cui sono associati diversi attributi che i materiali da costruzione non necessitano (e viceversa).
+----------+ +--------+ +---------+
|Grocery | |Product | |BuildMat |
|id (fk) +--->|id (pk) |<---+id (fk) |
|expiration| |desc | |material |
|... | |img | |... |
+----------+ |price | +---------+
|... |
+--------+
Ci sono momenti che richiedono in particolare una tabella EAV.
Considera la situazione in cui non stai semplicemente scrivendo un sistema di inventario per la tua azienda in cui conosci ogni prodotto e ogni attributo. Ora stai scrivendo un sistema di inventario da vendere ad altre società. Non puoi conoscere tutti gli attributi di ogni prodotto: dovranno definirli.
Un'idea che viene fuori è "lasciamo che il cliente modifichi la tabella" e questo è solo un male (entri nella meta-programmazione per le strutture delle tabelle perché non sai più dove si trovano, possono rovinare regalmente la struttura o corrompere l'applicazione, hanno accesso per fare cose sbagliate e le implicazioni di tale accesso diventano significative). C'è di più su questo percorso su MVC4: come creare un modello in fase di esecuzione?
Invece, si crea l'interfaccia amministrativa su una tabella EAV e si consente che venga utilizzata. Se il cliente desidera creare una voce per "polkadot", questa viene inserita nella tabella EAV e sai già come gestirla.
Un esempio di questo può essere visto nel modello di database per Redmine : puoi vedere la tabella custom_fields e la tabella custom_values - quelle sono parti dell'EAV che permettono di estendere il sistema.
Nota che se trovi che l'intera struttura della tabella assomiglia a EAV anziché relazionale, potresti voler guardare il sapore KV di NoSQL (cassandra, redis, Mongo, ...). Renditi conto che questi spesso presentano altri compromessi nel loro design che potrebbero essere o non essere appropriati per quello per cui lo stai usando. Tuttavia, sono progettati specificamente con l'intento di una struttura EAV.
Potresti voler leggere SQL vs NoSQL per un sistema di gestione dell'inventario
Seguendo questo approccio con un database NoSQL orientato ai documenti (couch, mongo), potresti considerare ogni articolo di inventario come un documento su un disco ... recuperare tutto in un singolo documento è veloce. Inoltre, il documento è strutturato in modo da poter estrarre rapidamente una sola cosa. D'altra parte, la ricerca di tutti i documenti per elementi che corrispondono a un particolare attributo può avere prestazioni inferiori (confronta usando 'grep' con tutti i file) ... è tutto un compromesso.
Un altro approccio sarebbe LDAP in cui si avrebbe una base con tutti i suoi elementi associati, ma si applicherebbero anche ulteriori classi di oggetti ad esso per gli altri tipi di elementi. (consultare Inventario del sistema tramite LDAP )
Una volta che si va su questa strada, si può trovare qualcosa che corrisponde esattamente quello che stai cercando ... se tutto viene fornito con alcuni compromessi.