Datamodellering - David Nueschelers modell
- Ämnen:
- Developing
Skapat för:
- Developer
Källa
Följande detaljer är idéer och kommentarer från David Nuescheler.
David var en av grundarna och CTO på Day Software AG, en ledande leverantör av programvara för global innehållshantering och innehållsinfrastruktur, som Adobe förvärvade 2010. Han är nu medlem i och VP för Enterprise Technology på Adobe och leder också utvecklingen av JSR-170, Java Content Repository (JCR), applikationsprogrammeringsgränssnittet (API), teknikstandarden för innehållshantering.
Ytterligare uppdateringar kan också visas på https://wiki.apache.org/jackrabbit/DavidsModel.
Introduktion från David
I olika diskussioner fann jag att utvecklarna är lite osäkra på de funktioner som JCR presenterade när det gäller innehållsmodellering. Det finns ännu ingen guide och mycket liten erfarenhet av att modellera innehåll i en databas och varför en innehållsmodell är bättre än den andra.
I den relationella världen har programvarubranschen en hel del erfarenhet av att modellera data, men vi är fortfarande i ett tidigt skede när det gäller innehållslagerutrymmet.
Jag skulle vilja börja fylla denna tomrumpa genom att uttrycka mina personliga åsikter om hur innehåll bör modelleras, och hoppas att detta en dag kan utexamineras i något mer meningsfullt för utvecklarcommunityn, som inte bara är "min åsikt" utan något som är mer allmänt tillämpligt. Så tänk på det här som min snabbaste början på det.
Sju enkla regler
Regel 1: Data först, struktur senare. Kanske.
Förklaring
Jag rekommenderar att man inte behöver bekymra sig om en deklarerad datastruktur i ett ERD-avseende. Inledningsvis.
Lär dig att älska inte:ostrukturerade (& vänner) under utvecklingen.
Jag tror att Stefano summerar det här.
Mitt resultat: Strukturen är dyr och i många fall är det helt onödigt att uttryckligen deklarera strukturen till den underliggande lagringen.
Det finns ett implicit kontrakt om strukturen som ditt program använder. Jag lagrar ändringsdatumet för ett blogginlägg i en lastModified-egenskap. Min app kan automatiskt läsa ändringsdatumet från samma egenskap igen, det finns ingen anledning att deklarera det uttryckligen.
Ytterligare databegränsningar som obligatoriska eller typ- och värdebegränsningar bör endast tillämpas där det är nödvändigt av dataintegritetsskäl.
Exempel
Ovanstående exempel på hur du använder en lastModified
Date-egenskap på till exempel bloggpost-nod betyder inte att det finns ett behov av en särskild nodtyp. Jag skulle definitivt använda nt:unstructured
för mina blogginläggsnoder åtminstone från början. Eftersom jag i mitt bloggprogram bara kommer att visa datumet lastModified i alla fall (eventuellt "order by") bryr jag mig knappt om det är ett datum alls. Eftersom jag ändå litar på att mitt blogginläggsprogram ska placera ett "datum" så finns det ingen anledning att deklarera en lastModified
datum i formatet a av nodtype.
Regel 2: Låt inte innehållshierarkin hända.
Förklaring
Innehållshierarkin är en mycket värdefull resurs. Så låt det inte bara hända, designa det. Om du inte har ett "bra", läsbart namn för en nod är det antagligen något du bör tänka om. Godtyckliga siffror är så gott som aldrig ett "bra namn".
Även om det kan vara extremt enkelt att snabbt lägga in en befintlig relationsmodell i en hierarkisk modell, bör man tänka lite i den processen.
Enligt min erfarenhet är det oftast bra drivrutiner för innehållshierarkin om man tänker på åtkomstkontroll och inneslutning. Tänk på det som om det vore ditt filsystem. Du kan till och med använda filer och mappar för att modellera dem på den lokala hårddisken.
Personligen föredrar jag hierarkiska konventioner framför nodetypsystemet i många fall först och sedan introducerar jag typningen senare.
Exempel
Jag skulle vilja skapa ett enkelt bloggsystem enligt följande. Observera att jag från början inte ens bryr mig om vilka nodtyper jag använder just nu.
/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
Jag tror att en av de saker som blir uppenbara är att vi alla förstår innehållets struktur baserat på exemplet utan några ytterligare förklaringar.
Det som till en början kan vara oväntat är varför jag inte skulle lagra "kommentarerna" med "posten", som beror på åtkomstkontroll som jag skulle vilja ha på ett rimligt hierarkiskt sätt.
Med innehållsmodellen ovan kan jag enkelt låta den anonyma användaren"skapa" kommentarer, men behålla den anonyma användaren skrivskyddad för resten av arbetsytan.
Regel 3: Arbetsytorna är för clone(), merge() och update().
Förklaring
Om du inte använder clone()
, merge()
eller update()
metoder i programmet som bara har en arbetsyta är antagligen den rätta.
"Motsvarande noder" är ett koncept som definieras i JCR-specifikationen. Det handlar i princip om noder som representerar samma innehåll, i olika så kallade arbetsytor.
JCR introducerar det mycket abstrakta begreppet Workspaces, vilket gör att många utvecklare inte vet vad de ska göra med dem. Jag vill föreslå att du använder arbetsytorna för att testa följande.
Om du har en avsevärd överlappning av"motsvarande" noder (i huvudsak noder med samma UUID) i flera arbetsytor kan du förmodligen använda arbetsytorna på ett bra sätt.
Om det inte finns någon överlappning av noder med samma UUID använder du antagligen arbetsytor.
Arbetsytor bör inte användas för åtkomstkontroll. Synlighet för innehåll för en viss användargrupp är inget bra argument för att dela upp saker i olika arbetsytor. JCR har "Åtkomstkontroll" i innehållsdatabasen för att tillhandahålla den.
Arbetsytor är gränsen för referenser och frågor.
Exempel
Använd arbetsytor för exempelvis:
- v1.2 av ditt projekt jämfört med v1.3 av ditt projekt
- ett"utvecklingstillstånd","QA" och ett"publicerat" innehållstillstånd
Använd inte arbetsytor för exempelvis:
- användarens hemkataloger
- distinkt innehåll för olika målgrupper som public, private, local, …
- e-postinkorgar för olika användare
Regel 4: Se upp för likasinnade namn.
Förklaring
Även om SNS (Same Name Siblings) har införts i specifikationen för att möjliggöra kompatibilitet med datastrukturer som är utformade för och uttryckta genom XML och därför är mycket värdefulla för JCR, har SNS en avsevärd belastning och komplexitet för databasen.
Alla sökvägar till innehållsdatabasen som innehåller en SNS i ett av dess sökvägssegment blir mycket mindre stabila, om en SNS tas bort eller sorteras om, påverkar det sökvägarna för alla andra SNS och deras underordnade.
För import av XML eller interaktion med befintlig XML SNS kan det vara nödvändigt och användbart, men jag har aldrig använt SNS och kommer aldrig att göra det i mina"gröna fältsdatamodeller".
Exempel
Använd
/content/myblog/posts/what_i_learned_today
/content/myblog/posts/iphone_shipping
i stället för
/content/blog[1]/post[1]
/content/blog[1]/post[2]
Regel 5: Referenser som betraktas som skadliga.
Förklaring
Referenser innebär referensintegritet. Jag tycker att det är viktigt att förstå att referenser inte bara medför extra kostnader för databasen som hanterar referensintegriteten, utan även är kostsamma ur ett flexibelt perspektiv.
Personligen ser jag till att jag bara använder referenser när jag inte kan hantera en farlig referens och i annat fall använda en sökväg, ett namn eller en sträng-UID för att referera till en annan nod.
Exempel
Låt oss anta att jag tillåter "referenser" från ett dokument (a) till ett annat dokument (b). Om jag modellerar den här relationen med hjälp av referensegenskaper innebär det att de två dokumenten är länkade på en databasnivå. Jag kan inte exportera/importera dokument (a) separat, eftersom referensegenskapens mål kanske inte finns. Även andra åtgärder som sammanfogning, uppdatering, återställning och kloning påverkas.
Därför skulle jag antingen modellera dessa referenser som "svag referens" (i JCR v1.0 så här böjer det sig i princip ned till strängegenskaper som innehåller målnodens uuid) eller bara använda en sökväg. Ibland är banan mer meningsfull att börja med.
Jag tror att det finns situationer där ett system verkligen inte fungerar om en referens är farlig, men jag kan inte komma på ett bra "verkligt" men ändå enkelt exempel från min direkta erfarenhet.
Regel 6: Filer är filer.
Förklaring
Om en innehållsmodell visar något som till och med finns på fjärrbasis illaluktande som en fil eller en mapp som jag försöker använda (eller utöka från) nt:file
, nt:folder
och nt:resource
.
Enligt min erfarenhet tillåter många generiska program interaktion med nt:folder och nt:files implicit och vet hur de ska hantera och visa dessa händelser om de har berikats med ytterligare metainformation. En direkt interaktion med filserverimplementeringar som CIFS eller WebDAV som sitter ovanpå JCR blir till exempel implicit.
Jag tror att en bra tumregel kan behöva följande: Om du behöver lagra filnamnet och mime-typen kan du nt:file
/ nt:resource
är en väldigt bra match. Om du kan ha flera "filer" kan det vara bra att spara dem i mappen nt:folder.
Om du behöver lägga till metainformation för resursen kan du utöka nt:resource
inte nt:file
. sällan utöka nt:resource
.
Exempel
Låt oss anta att någon vill ladda upp en bild till ett blogginlägg på:
/content/myblog/posts/iphone_shipping
och kanske den initiala uttarningsreaktionen är att lägga till en binär egenskap som innehåller bilden.
Även om det finns bra användningsexempel för att bara använda en binär egenskap (vi ska säga att namnet är irrelevant och att mime-typen är implicit) i det här fallet rekommenderar jag följande struktur för bloggexemplet.
/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]
Regel 7: ID:n är onda.
Förklaring
I relationsdatabaser är id:n ett nödvändigt sätt att uttrycka relationer, så folk tenderar att använda dem även i innehållsmodeller. Mestadels av fel skäl.
Om innehållsmodellen är full av egenskaper som slutar på"ID" använder du förmodligen inte hierarkin korrekt.
Det är sant att vissa noder behöver en stabil identifiering under hela sin livscykel. Mycket färre än du tror. mix:referenceable innehåller en sådan mekanism som är inbyggd i databasen, så det finns inget behov av att hitta ytterligare sätt att identifiera en nod på ett stabilt sätt.
Tänk också på att objekt kan identifieras med sökväg, och så mycket som "symlinks" är mer användbart för de flesta användare än maskinlänkar i ett enhetligt filsystem, är en sökväg ett bra sätt för de flesta program att referera till en målnod.
Ännu viktigare är det mix:referenable, vilket betyder att det kan användas på en nod vid den tidpunkt då du faktiskt behöver referera till den.
Låt oss säga bara för att du vill kunna referera till en nod av typen"Dokument" innebär det inte att din"Dokument"-nodtyp måste byggas ut från mix:referenable på ett statiskt sätt eftersom den kan läggas till dynamiskt i alla instanser av"Dokument".
Exempel
Använd:
/content/myblog/posts/iphone_shipping/attachments/front.jpg
i stället för:
[Blog]
-- blogId
-- author
[Post]
-- postId
-- blogId
-- title
-- text
-- date
[Attachment]
-- attachmentId
-- postId
-- filename
+ resource (nt:resource)
Experience Manager
- Utveckla användarhandboken - översikt
- Introduktion för utvecklare
- Komma igång med utveckling i AEM Sites – WKND-självstudiekurs
- AEM kärnbegrepp
- Struktur för det AEM användargränssnittet med pekskärm
- Koncepten i det AEM användargränssnittet med pekskärm
- AEM - riktlinjer och bästa praxis
- Använda bibliotek på klientsidan
- Developing and Page Diff
- Begränsningar för redigerare
- CSRF Protection Framework
- Datamodellering - David Nueschelers modell
- Bidrar till AEM
- Dokumentskydd
- Referensmaterial
- Skapa en webbplats med alla funktioner (Classic UI)
- Designer och Designer (Classic UI)
- Plattform
- Fusklapp för Sling
- Använda Sling-adaptrar
- Taggbibliotek
- Mallar
- Använda Sling Resource Merger i AEM
- Övertäckningar
- Namnkonventioner
- Skapa en ny GRE-fältkomponent
- Query Builder
- Taggar
- Anpassa sidor som visas av felhanteraren
- Anpassade nodtyper
- Lägga till teckensnitt för grafikåtergivning
- Ansluta till SQL-databaser
- Extern URL
- Skapa och använda jobb för avlastning
- Konfigurerar cookie-användning
- Så här programmässigt kommer du åt AEM JCR
- Integrera tjänster med JMX-konsolen
- Developing the Bulk Editor
- Utveckla rapporter
- eCommerce
- Komponenter
- Kärnkomponenter
- Formatsystem
- Komponenter - översikt
- AEM - Grunderna
- Utveckla AEM
- Utveckla AEM - kodexempel
- JSON-exporterare för innehållstjänster
- Aktivera JSON-export för en komponent
- Bildredigeraren
- Dekoration-tagg
- Använda Dölj villkor
- Konfigurera flera redigerare på plats
- Utvecklarläge
- Testa användargränssnittet
- Komponenter för innehållsfragment
- Hämta sidinformation i JSON-format
- Internationalisering
- Klassiska gränssnittskomponenter
- Headless Experience Management
- Headless och Hybrid with AEM
- Aktivera JSON-export för en komponent
- Enkelsidiga program
- SPA introduktion och genomgång
- SPA WKND - självstudiekurs
- Getting Started with SPA in AEM - React
- Komma igång med SPA i AEM - Angular
- Implementera en React Component for SPA
- SPA djupdykning
- SPA
- Utveckla SPA för AEM
- SPA Blueprint
- SPA
- Dynamisk mappning av modell till komponent för SPA
- SPA
- SPA och Adobe Experience Platform Launch Integration
- SPA- och serveråtergivning
- SPA referensmaterial
- HTTP-API
- Innehållsfragment
- Experience Fragments
- Utvecklingsverktyg
- Utvecklingsverktyg
- AEM Modernization Tools
- Dialogruteredigeraren
- Verktyget Dialogkonvertering
- Utveckla med CRXDE Lite
- Hantera paket med Maven
- Utveckla AEM projekt med Eclipse
- Skapa AEM projekt med Apache Maven
- Utveckla AEM projekt med IntelliJ IDEA
- Så här använder du VLT-verktyget
- Så här använder du proxyserververktyget
- AEM Brackets Extension
- AEM Developer Tools for Eclipse
- AEM
- Personanpassning
- Utöka AEM
- Anpassa sidredigering
- Anpassa konsolerna
- Anpassa vyer av Sidegenskaper
- Konfigurera din sida för gruppredigering av sidegenskaper
- Anpassa och utöka Content Fragments
- Utöka arbetsflöden
- Utöka Multi Site Manager
- Spårning och analys
- Cloud Services
- Skapa anpassade tillägg
- Forms
- Integrera tjänster med JMX-konsolen
- Developing the Bulk Editor
- Utöka Classic UI
- Testning
- Bästa praxis
- Mobil webb