Show Menu
ARGOMENTI×

Data Modeling - Modello di David Nuescheler

Origine

I seguenti dettagli sono idee e commenti espressi da David Nuescheler.
David è stato co-fondatore e CTO of Day Software AG, uno dei principali fornitori di software per la gestione dei contenuti e l'infrastruttura a livello globale, richiesto da Adobe nel 2010. È ora membro e vicepresidente della tecnologia Enterprise di Adobe e guida lo sviluppo di JSR-170, l'API (Application Programming Interface) Java Content Repository (JCR), lo standard tecnologico per la gestione dei contenuti.
Ulteriori aggiornamenti sono disponibili su https://wiki.apache.org/jackrabbit/DavidsModel .

Introduzione da David

In varie discussioni ho scoperto che gli sviluppatori sono in qualche modo a disagio con le caratteristiche e funzionalità presentate da JCR quando si tratta di modellazione del contenuto. Non esiste una guida e non c'è ancora molta esperienza su come modellare il contenuto in un repository e sul motivo per cui un modello di contenuto è migliore dell'altro.
Mentre nel mondo relazionale l'industria del software ha molta esperienza su come modellare i dati, siamo ancora alle prime fasi per lo spazio archivio dei contenuti.
Vorrei iniziare a riempire questo vuoto esprimendo le mie opinioni personali su come il contenuto dovrebbe essere modellato, sperando che un giorno possa diventare qualcosa di più significativo per la comunità degli sviluppatori, che non è solo "la mia opinione", ma qualcosa di più generale applicabile. Considerate questo mio primo attacco in rapida evoluzione.
Dichiarazione di non responsabilità: Queste linee guida esprimono le mie opinioni personali, talvolta controverse. Sono ansioso di discutere di questi orientamenti e di perfezionarli.

Sette regole semplici

Regola n. 1: Prima i dati, poi la struttura. Forse.

Spiegazione

Raccomando di non preoccuparsi di una struttura di dati dichiarata in senso ERD. Inizialmente.
Imparare ad amare non:non strutturati (&) nello sviluppo.
Credo che Stefano riassuma questo.
La mia linea di fondo: La struttura è costosa e in molti casi non è assolutamente necessario dichiarare esplicitamente la struttura allo stoccaggio sottostante.
Esiste un contratto implicito sulla struttura che l'applicazione utilizza in modo intrinseco. Supponiamo di memorizzare la data di modifica di un post di blog in una proprietà lastModified. La mia App saprà automaticamente leggere la data di modifica di quella stessa proprietà, non c'è davvero bisogno di dichiararlo esplicitamente.
Ulteriori vincoli relativi ai dati, come i vincoli obbligatori o di tipo e di valore, dovrebbero essere applicati solo se necessario per motivi di integrità dei dati.

Esempio

L'esempio precedente relativo all'utilizzo di una proprietà lastModified Date, ad esempio nel nodo "post di blog", non significa in realtà che sia necessario un tipo di nodo speciale. Utilizzerei sicuramente nt:unstructured per i miei nodi post di blog almeno inizialmente. Dal momento che nella mia applicazione di blog tutto ciò che farò è mostrare la data dell'ultima modifica comunque (forse "ordine entro") mi importa a malapena se è un Data. Dato che mi fido implicitamente della mia applicazione di scrittura di blog per inserire una "data" comunque, non c'è davvero bisogno di dichiarare la presenza di una data nella forma di un nodetype. lastModified

Regola n. 2: Guidare la gerarchia dei contenuti, non lasciarla accadere.

Spiegazione

La gerarchia dei contenuti è una risorsa molto preziosa. Quindi non lasciate che accada, progettatelo. Se non avete un nome "buono" e leggibile per un nodo, probabilmente è qualcosa che dovreste riconsiderare. I numeri arbitrari non sono mai un "buon nome".
Anche se può essere estremamente facile mettere rapidamente un modello relazionale esistente in un modello gerarchico, si dovrebbe riflettere in quel processo.
Nella mia esperienza, se si pensa al controllo degli accessi e al contenimento, in genere buoni driver per la gerarchia dei contenuti. Pensatelo come se fosse il vostro file system. Forse anche utilizzare file e cartelle per modellare sul disco locale.
Personalmente preferisco le convenzioni gerarchiche rispetto al sistema di digitazione dei nodi in molti casi inizialmente, e introdurre la digitazione successivamente.
Anche la struttura di un archivio dei contenuti può influire sulle prestazioni. Per ottenere prestazioni ottimali, il numero di nodi secondari associati a singoli nodi in un archivio dei contenuti non deve in genere superare 1000.
Vedere Quanti dati è in grado di gestire il CRX? per ulteriori informazioni.

Esempio

Vorrei modellare un semplice sistema di blog come segue. Nota che inizialmente non mi interessa nemmeno i rispettivi tipi di nodi che uso a questo punto.
/content/myblog
/content/myblog/posts
/content/myblog/posts/what_i_learned_today
/content/myblog/posts/iphone_shipping

/content/myblog/comments/iphone_shipping/i_like_it_too
/content/myblog/comments/iphone_shipping/i_like_it_too/i_hate_it

Credo che una delle cose che si sono rese evidenti è che tutti comprendiamo la struttura del contenuto basata sull'esempio senza ulteriori spiegazioni.
Ciò che potrebbe essere inaspettato inizialmente è il motivo per cui non avrei memorizzato i "commenti" con il "post", che è dovuto al controllo di accesso che mi piacerebbe essere applicato in modo ragionevolmente gerarchico.
Utilizzando il modello di contenuto sopra riportato, posso facilmente consentire all'utente "anonimo" di "creare" commenti, ma mantenere l'utente anonimo in sola lettura per il resto dell'area di lavoro.

Regola n. 3: Le aree di lavoro sono per clone(), merge() e update().

Spiegazione

Se non si utilizzano clone() , merge() o update() metodi nell'applicazione è probabile che un'unica area di lavoro sia la strada giusta.
"nodi corrispondenti" è un concetto definito nella specifica JCR. Essenzialmente, si riduce a nodi che rappresentano lo stesso contenuto, in diverse aree di lavoro.
JCR introduce il concetto molto astratto di Workspaces che lascia molti sviluppatori poco chiari su cosa fare con loro. Vorrei proporre di sottoporre a test l'uso dei vostri spazi di lavoro.
Se si ha una sovrapposizione notevole di nodi "corrispondenti" (essenzialmente i nodi con lo stesso UUID) in più aree di lavoro, è probabile che le aree di lavoro siano utili.
Se non vi è sovrapposizione di nodi con lo stesso UUID, probabilmente si abuseranno di aree di lavoro.
Le aree di lavoro non devono essere utilizzate per il controllo degli accessi. La visibilità del contenuto per un particolare gruppo di utenti non è un buon argomento per separare gli elementi in aree di lavoro diverse. JCR dispone di "Controllo accesso" nell'archivio dei contenuti per fornire tali informazioni.
Le aree di lavoro sono il limite per riferimenti e query.

Esempio

Utilizzare aree di lavoro per attività quali:
  • v1.2 del progetto rispetto a v1.3 del progetto
  • uno stato di "sviluppo", "QA" e "pubblicato"
Non utilizzate aree di lavoro per elementi quali:
  • directory home utente
  • contenuto distinto per diversi tipi di pubblico target come pubblico, privato, locale, ...
  • caselle di posta elettronica per diversi utenti

Regola n. 4: Fai attenzione ai fratelli con lo stesso nome.

Spiegazione

Mentre SNS (Same Name Siblings) è stato introdotto nella specifica per consentire la compatibilità con le strutture di dati progettate per e espresse tramite XML e quindi estremamente preziose per JCR, SNS presenta un sovraccarico e una complessità notevoli per il repository.
Qualsiasi percorso all'interno dell'archivio dei contenuti che contiene un SNS in uno dei suoi segmenti di percorso diventa molto meno stabile. Se un SNS viene rimosso o riordinato, questo avrà un impatto sui percorsi di tutti gli altri SNS e dei relativi elementi secondari.
Per l'importazione di XML o per l'interazione con SNS XML esistenti può essere necessario e utile, ma non ho mai utilizzato SNS e non lo sarà mai nei miei modelli di dati "campo verde".

Esempio

Utilizzo
/content/myblog/posts/what_i_learned_today
/content/myblog/posts/iphone_shipping

anziché
/content/blog[1]/post[1]
/content/blog[1]/post[2]

Regola n. 5: Riferimenti considerati dannosi.

Spiegazione

I riferimenti implicano l'integrità referenziale. È importante comprendere che i riferimenti non comportano solo un costo aggiuntivo per il repository che gestisce l'integrità referenziale, ma sono anche costosi dal punto di vista della flessibilità dei contenuti.
Personalmente mi assicuro di utilizzare sempre i riferimenti solo quando non riesco davvero a gestire un riferimento pericoloso e altrimenti uso un percorso, un nome o una stringa UUID per fare riferimento a un altro nodo.

Esempio

Supponiamo di consentire "riferimenti" da un documento (a) a un altro documento (b). Se faccio un modello di questa relazione utilizzando le proprietà di riferimento, ciò significa che i due documenti sono collegati a livello di repository. Non è possibile esportare/importare documenti (a) singolarmente, poiché la destinazione della proprietà di riferimento potrebbe non esistere. Vengono interessate anche altre operazioni quali unione, aggiornamento, ripristino o duplicazione.
Quindi potrei modellare questi riferimenti come "riferimenti deboli" (in JCR v1.0 questo sostanzialmente si riduce a proprietà stringa che contengono l'uuid del nodo di destinazione) o semplicemente utilizzare un percorso. A volte il percorso è più significativo per iniziare.
Penso che ci siano casi d'uso in cui un sistema non può realmente funzionare se un riferimento è penzolante, ma non riesco a trovare un buon esempio "reale" ma semplice dalla mia esperienza diretta.

Regola n. 6: I file sono file.

Spiegazione

Se un modello di contenuto espone qualcosa che ha anche un odore remoto come un file o una cartella che cerco di utilizzare (o estendere da) nt:file , nt:folder e nt:resource .
Nella mia esperienza molte applicazioni generiche consentono l'interazione con nt:folder e nt:files in modo implicito e sanno come gestire e visualizzare tali eventi se sono arricchiti con ulteriori metadati. Ad esempio, un'interazione diretta con le implementazioni del file server come CIFS o WebDAV che si trovano sopra JCR diventa implicita.
Credo che, come buona regola, si possa usare quanto segue: Se dovete memorizzare il nome del file e il tipo mime allora nt:file / nt:resource è una corrispondenza molto buona. Se si possono avere più "file", un nt:folder è un buon punto in cui memorizzarli.
Se è necessario aggiungere metadati per la risorsa, ad esempio una proprietà "author" o "description", estendere nt:resource non la nt:file . Estendo raramente nt:file e frequentemente nt:resource .

Esempio

Supponiamo che qualcuno voglia caricare un'immagine in un post del blog all'indirizzo:
/content/myblog/posts/iphone_shipping

e forse la reazione iniziale dell'intestino sarebbe di aggiungere una proprietà binaria che contiene l'immagine.
Anche se ci sono sicuramente buoni casi d'uso per utilizzare solo una proprietà binaria (diciamo che il nome è irrilevante e il mime-type è implicito) in questo caso, consiglierei la seguente struttura per il mio esempio di blog.
/content/myblog/posts/iphone_shipping/attachments [nt:folder]
/content/myblog/posts/iphone_shipping/attachments/front.jpg [nt:file]
/content/myblog/posts/iphone_shipping/attachments/front.jpg/jcr:content [nt:resource]

Regola n. 7: Gli ID sono malvagi.

Spiegazione

Nei database relazionali gli ID sono un mezzo necessario per esprimere le relazioni, in modo che le persone tendono ad utilizzarli anche nei modelli di contenuto. Principalmente per le ragioni sbagliate.
Se il modello di contenuto è pieno di proprietà che terminano con "Id", probabilmente non state utilizzando correttamente la gerarchia.
È vero che alcuni nodi necessitano di un'identificazione stabile durante tutto il loro ciclo di vita. Molto meno di quanto potresti pensare. mix:referenceable fornisce un meccanismo di questo tipo integrato nel repository, quindi non c'è davvero bisogno di trovare un modo aggiuntivo per identificare un nodo in modo stabile.
Tenete anche presente che gli elementi possono essere identificati per percorso, e tanto più che "symlinks" ha senso per la maggior parte degli utenti che non i collegamenti diretti in un file system unix, un percorso ha senso per la maggior parte delle applicazioni fare riferimento a un nodo di destinazione.
Ma soprattutto, è mix :referenceable, il che significa che può essere applicato a un nodo nel momento in cui è effettivamente necessario farvi riferimento.
Diciamo che solo perché si desidera poter fare riferimento potenzialmente a un nodo di tipo "Documento" non significa che il tipo di nodo "Documento" deve estendersi da mix:referenceable in modo statico, in quanto può essere aggiunto a qualsiasi istanza del "Documento" in modo dinamico.

Esempio

Utilizzo:
/content/myblog/posts/iphone_shipping/attachments/front.jpg

anziché:
[Blog]
-- blogId
-- author
[Post]
-- postId
-- blogId
-- title
-- text
-- date
[Attachment]
-- attachmentId
-- postId
-- filename
+ resource (nt:resource)