16

Se è necessario creare un'applicazione come, ad esempio un'applicazione per blog, la creazione dello schema del database è relativamente semplice. Devi creare alcune tabelle, tblPosts, tblAttachments, tblCommets, tblBlaBla ... e questo è tutto (ok, lo so, è un po 'semplificato ma capisci cosa intendo).Come progettare il database per consentire lo schema definito dall'utente

Cosa succede se si dispone di un'applicazione in cui si desidera consentire agli utenti di definire parti dello schema in fase di esecuzione. Supponiamo che tu desideri creare un'applicazione in cui gli utenti possano registrare qualsiasi tipo di dati. Un utente vuole registrare il suo orario di lavoro (startTime, endTime, Id del progetto, descrizione), il prossimo vuole raccogliere ricette di cucina, altre forse quotazioni di borsa, il peso settimanale dei loro bambini, spese mensili spese per il cibo, i risultati delle loro squadre di calcio preferite o qualsiasi altra cosa a cui puoi pensare.

Come si progetta un database per contenere tutto questo molto molto diverso tipo di dati? Creeresti uno schema generico in grado di contenere tutti i tipi di dati, creerai nuove tabelle che riflettono lo schema dei dati utente o hai un'altra grande idea per farlo?

Se è importante: "impazzire" Devo usare/Entity Framework SQL Server

risposta

0

vorrei solo dare loro una copia di SQL Server Management Studio, e dire: Perché reinventare una ruota all'interno di una ruota?

+0

Non è una buona idea poiché l'utente non ha idea di cosa sia "SQL" o "Management Studio". Risposta divertente ma non molto utile. – JRoppert

3

Sulla superficie, un database senza schema o orientato ai documenti come CouchDB o SimpleDB per i dati utente personalizzati sembra ideale. Ma immagino che non sia di grande aiuto se non puoi usare altro che SQL ed EF.

3

Non ho familiarità con Entity Framework, ma preferirei il modello di database Entity-Attribute-Value (http://en.wikipedia.org/wiki/Entity-Attribute-Value_model).

Quindi, anziché creare al volo tabelle e colonne, l'app creava attributi (o raccolte di attributi) e quindi gli utenti finali completavano i valori.

Ma, come ho detto, non so che cosa dovrebbe fare per te Entity Framework e potrebbe non consentirgli di adottare questo approccio.

+0

FWIW, Entity Framework è una libreria ORM nascente per il framework Microsoft .NET. –

+0

Grazie per quel Bill - Non sono un ragazzo di .NET quindi non ne ho mai sentito parlare. Sto pensando, però, che un ORM avrebbe problemi con l'EAV? – Antony

+0

È possibile con ORM (in realtà più facile!), È possibile avere un'interfaccia di oggetti di business che è composta da alcune proprietà dell'interfaccia EAV. per esempio. IEntity è composto dall'Elenco in cui IAttribute è composto dall'Elenco (e anche i collegamenti a IEntity). Fintanto che definisci i tuoi valori di entità -> attributo -> nel modo standard utilizzato dal tuo strumento ORM, è come qualsiasi altra relazione. – si618

0

Dai un'occhiata a questo post puoi farlo ma è un sacco di duro lavoro :) Se le prestazioni non sono un problema, una soluzione xml potrebbe funzionare anche se questo è anche un sacco di lavoro.

+0

Conosco quell'articolo ma non ho idea del perché questa dovrebbe essere una risposta alla mia domanda !? – JRoppert

+0

Abbastanza onesto, è stata una rapida risposta. Ovviamente potresti lasciare le parti "dinamiche" dello schema ad un altro motore che è comunque la bellezza del design guidato da domini, ma ho difficoltà a capire come risolverlo con EF o L2S. Intendo quale tipo di applicazione sarebbe mirata alla registrazione di tutti i vari bisogni? È solo per divertimento o è un vero progetto? – mhenrixon

9

Non è possibile prevedere quanto complessi saranno i loro requisiti di dati. Entity-Attribute-Value è una soluzione tipica che molti programmatori usano, ma potrebbe essere sufficiente, ad esempio se i dati dell'utente sarebbero convenzionalmente modellati con più tabelle.

Vorrei serializzare i dati personalizzati dell'utente come XML o YAML o JSON o simile formato semistrutturato e salvarlo in un BLOB di testo.

È anche possibile creare indici invertiti in modo da poter cercare valori specifici tra gli attributi nel proprio BLOB. Vedi http://bret.appspot.com/entry/how-friendfeed-uses-mysql (la tecnica funziona su qualsiasi RDBMS, non solo su MySQL).

Considerare inoltre l'utilizzo di un archivio documenti come Solr o MongoDB. Queste tecnologie non devono essere conformi alle convenzioni del database relazionale. È possibile aggiungere nuovi attributi a qualsiasi documento in fase di esecuzione, senza la necessità di ridefinire lo schema. Ma è un compromesso: non avere schemi significa che la tua app non può dipendere dal fatto che documenti/righe siano simili in tutta la collezione.


Sono un critico del anti-pattern Entity-Attribute-Value.

Ho scritto sui problemi EAV nel mio libro, SQL Antipatterns: Avoiding the Pitfalls of Database Programming.

Ecco una risposta SO in cui elencho alcuni problemi con Entity-Attribute-Value: "Product table, many kinds of products, each product has many parameters".

Ecco un blog che ho postato l'altro giorno con alcune discussioni in più sui problemi EAV: "EAV FAIL".

E assicurati di leggere questo blog "Bad CaRMa" su come il tentativo di creare un database completamente flessibile ha quasi distrutto un'azienda.

+0

Cura di elaborare le tue critiche a EAV Bill? Penso che abbia il suo posto, anche se ovviamente ci sono dei vincoli, ma vedi il link nella mia risposta. – si618

+0

un blob per tutto? che schifo! questo renderà anche semplicemente semplice la segnalazione praticamente impossibile, inoltre sarà più difficile ottenere buone prestazioni. –

+0

@Booji Boy: Sono d'accordo, scegliere XML (o qualsiasi altra cosa) è difficile in SQL, ma l'OP non ha detto che aveva bisogno di fare qualsiasi segnalazione. È altrettanto probabile che l'intero BLOB debba essere caricato nell'applicazione per fare qualsiasi cosa l'utente volesse fare con esso. E 'difficile da prevedere comunque. –

5

Vorrei andare per un modello di Entity-Attribute-Value ibrido, quindi come la risposta di Antony, hai tabelle EAV, ma hai anche colonne predefinite (e proprietà di classe) che esisteranno sempre.

Ecco un great article su ciò che ci si trova per :)

Come un commento aggiuntivo, ho bussato un prototipo di questo approccio utilizzando Linq2Sql in pochi giorni, ed era una soluzione praticabile. Dato che hai menzionato Entity Framework, darei un'occhiata alla versione 4 e al loro POCO support, poiché questo sarebbe un buon modo per iniettare un modello EAV ibrido senza inquinare lo schema EF.

+0

Questo è un ottimo articolo che hai trovato Si - aggiunto ai preferiti per la prossima volta! – Antony

1

Non come un commento critico, ma può aiutare a risparmiare un po 'di tempo per sottolineare che questo è uno di quei problemi del tipo del Santo Graal del Don Chisciotte. C'è una ricerca eterna probabilmente da oltre 50 anni per creare un'interfaccia di progettazione di database user-friendly.

Gli unici quasi di successo che hanno ottenuto una trazione significativa a cui riesco a pensare sono 1. Excel (ei suoi predecessori), 2. Filemaker (l'originale, non il suo attuale sapore) e 3. (possibilmente, ma dubbioso) Accesso. Si noti che i primi due sono limitati a fondamentalmente una tabella.

Sarei sorpreso se la nostra saggezza collettiva convenzionale ti aiuterà a superare la barriera. Ma sarebbe meraviglioso.

+0

In secondo luogo, si può essere molto limitati e totalmente non performanti con qualche schema di attributo di entità, oppure, si può inventare qualcosa di flessibile, complesso e un incubo da mantenere che è solo una pessima implementazione del linguaggio di definizione dei dati. –

1

Anziché reimplementare l'istruzione "CREATE TABLE" di sqlservers, che è stata eseguita molti anni fa da un team di programmatori che erano probabilmente migliori di te o me, perché non lavorare sull'esposizione di SQLSERVER in modo limitato agli utenti: - Lascia che creino il proprio schema in modo limitato e sfrutti la potenza di SQLServer per farlo correttamente.

+0

Questo è davvero un grande commento. Ma poiché questa è una domanda di struttura di entità, richiederebbe l'aggiornamento delle tue entità per incorporare questi campi. Quindi potresti anche solo aggiungerli. In secondo luogo, vale la pena notare che gli utenti che cambiano lo schema SQL potrebbero avere gravi implicazioni sulle prestazioni (piani di esecuzione che devono essere ricalcolati, ecc.) –

11

Proviamo di nuovo.

Se si desidera che siano in grado di creare il proprio schema, perché non creare lo schema utilizzando, oh, non so, la statuetta CREATE TABLE. Disponi di un database completo, completo, funzionale e potente che può fare cose incredibili come definire schemi e memorizzare dati. Perché non usarlo?

Se stavate solo facendo alcune proprietà ad-hoc, quindi sicuro.

Ma se è "carta bianca, possono fare tutto ciò che vogliono", quindi lasciarli.

Devono conoscere SQL? Umm, no. Questo è il tuo compito di interfaccia utente. Il tuo lavoro come strumento e progettista dell'applicazione è quello di nascondere l'implementazione all'utente. Così presenti liste di campi, linee e frecce se vuoi relazioni, ecc. Qualunque cosa.

Per anni gli utenti hanno creato strumenti di database "semplici", "semplici".

"E se volessero aggiungere una colonna?" Quindi aggiungi una colonna, i database lo fanno, almeno quelli più buoni. In caso contrario, creare la nuova tabella, copiare i vecchi dati, eliminare quello precedente.

"Che cosa succede se vogliono eliminare una colonna?" Vedi sopra. Se il tuo non può rimuovere le colonne, rimuoverlo dalla vista logica dell'utente in modo che sembri cancellato.

"Che cosa succede se dispongono di un numero di file di dati di undicimila?" Poi hanno un numero di miliardi di file di dati e le operazioni impiegano più di venti miliardi di volte più a lungo di se avessero una riga di dati. Se hanno un massimo di zilioni di file di dati, probabilmente non dovrebbero comunque usare il sistema per questo.

Il fascino di "Implementazione di database su database" mi sfugge.

"Ho Oracle qui, come posso offrire meno funzioni e rendere più lento per l'utente ??"

Accidenti, mi chiedo.

+0

Hai dimenticato di menzionare gli indici. Nessun wrapper del database è pronto a meno che non fornisca un modo per indicizzare tutti i nuovi attributi e quindi ci sia ... – quixver

+1

finalmente una risposta ragionevole su questo argomento. –

+1

"Il fascino di" Implementare database su database "mi sfugge." Fantastico!! :) –

Problemi correlati