Mönster för materialiserad vy

Generera förifyllda vyer över data i ett eller flera datalager när data inte är idealiskt formaterade för nödvändiga frågeåtgärder. Den här metoden kan stödja effektiv frågekörning och extrahering av data och förbättra programmets prestanda.

Kontext och problem

När du lagrar data prioriterar utvecklare och dataadministratörer ofta hur data lagras i stället för hur de läss. Det valda lagringsformatet återspeglar vanligtvis dataformatet, kraven för att hantera datastorlek och dataintegritet och vilken typ av lagring som används. När du till exempel använder ett NoSQL dokumentarkiv representerar du ofta data som en serie aggregeringar, som var och en innehåller all information för den entiteten.

Den här metoden kan dock ha en negativ effekt på frågor. När en fråga endast behöver en delmängd data från vissa enheter, till exempel en ordersammanfattning för flera kunder, utan all orderinformation, så måste alla data för de relevanta entiteterna extraheras för att det ska gå att få fram den information som krävs.

Att lägga till index eller omforma frågor vid lästid löser inte alltid den här ineffektiviteten. Många datalager kan inte omindexeras för godtyckliga läsåtkomstmönster utan att påverka skrivprestandan. Sammansättning mellan entiteter är fortfarande dyrt vid frågetillfället. Vissa butiker har begränsade frågefunktioner avsiktligt. På grund av dessa begränsningar räcker det ofta inte att optimera lässökvägen i källarkivet.

Lösning

För att stödja effektiv frågebearbetning är en vanlig lösning att i förväg generera en vy som materialiserar data i ett format som lämpar sig för den efterfrågade resultatuppsättningen. Mönstret för den materialiserade vyn beskriver generering av förifyllda datavyer i miljöer där datakällan inte är i ett lämpligt format för frågor, där det är svårt att generera en lämplig fråga eller där frågeprestandan är dålig på grund av datautformningen eller utformningen av datalagret.

I det här mönstret är en materialiserad vy en läsmodell eller projektion som bevarar data som härleds från ett eller flera källlager. En dedikerad programkomponent eller datapipeline kan underhålla projektionen, inklusive över butiksgränser. Konsumenter av frågor behandlar projektionen som endast läsbar. Det här arkitekturkonceptet är bredare än ett databasbaserat materialiserat vyobjekt, som en databasmotor definierar, lagrar och uppdaterar enligt sina egna funktionsbegränsningar.

Dessa materialiserade vyer, som endast innehåller data som krävs av en fråga, gör det möjligt för program att snabbt få den information de behöver. Utöver funktioner för att koppla samman tabeller och kombinera dataentiteter kan materialiserade vyer innehålla de aktuella värdena för beräknade kolumner eller dataobjekt, resultatet av kombinerade värden eller transformeringskörningar på dataobjekten och värden som anges som en del av frågan. En materialiserad vy kan till och med optimeras för en enda fråga.

En viktig punkt är att en materialiserad vy och de data den innehåller är helt disponibla eftersom de kan återskapas helt från källdatalager. Frågekonsumenter uppdaterar inte vyn direkt. I stället underhåller en dedikerad komponent, datapipeline eller databasmotor den, så det är en specialiserad cache.

När källdata för vyn ändras måste vyn uppdateras för att inkludera den nya informationen. Du kan schemalägga uppdateringen så att den sker automatiskt eller när systemet identifierar en ändring av de ursprungliga data. I vissa fall kan du behöva återskapa vyn manuellt. Följande bild visar ett exempel på hur mönstret Materialiserad vy kan användas.

Diagram som visar ett exempel på hur mönstret materialiserad vy kan användas.

Problem och överväganden

Tänk på följande när du bestämmer hur du ska implementera det här mönstret:

  • Visa uppdateringsstrategi. Helst återskapas vyn som svar på en händelse som indikerar en ändring av källdata, även om den här metoden kan leda till alltför stora omkostnader om källdata ändras snabbt. Du kan även överväga att använda en schemalagd uppgift, en extern utlösare eller en manuell åtgärd för att återskapa vyn.

  • Uppdateringsbeteende. Avgör om implementeringen utför en fullständig ombyggnad eller tillämpar ändringar stegvis. Du måste också bestämma om uppdateringsåtgärderna blockerar läsningar.

    Dessa beslut avgör om frågor returnerar potentiellt inaktuella materialiserade data, kombinerar materialiserade data med obearbetade källändringar för att returnera aktuella resultat eller fortsätter att hantera den senaste fullständiga versionen tills uppdateringen har slutförts.

  • Uppdatera signalens tillförlitlighet. Om aktiveringssignalen som utlöser visningsregenerering går förlorad eller fördröjs – till exempel en missad ändringsflödeshändelse eller en misslyckad schemalagd aktivitet – ger vyn tyst inaktuella resultat. Övervaka hur nyligen vyn uppdaterades och varna när vyns ålder överskrider den acceptabla gränsen för inaktualitet.

  • Uppdatera beräkningskostnaden. Om du återskapar en vy används beräkningsresurser som är proportionella mot mängden källdata och komplexiteten i omvandlingarna. För händelsedriven uppdatering av snabbt föränderliga källdata, eller för fullständiga återskapanden av stora analytiska vyer, kan beräkningskostnaden för uppdatering vara en betydande kostnadsdrivande faktor. Anpassa uppdateringsfrekvensen och omfattningen för att balansera hur aktuella data är mot beräkningskostnaderna.

  • Beroende av Event Sourcing I vissa system, till exempel när du använder Event Sourcing-mönstret för att upprätthålla ett händelselager som endast innehåller de händelser som ändrat data, är materialiserade vyer vanligtvis nödvändiga. Det kan vara så att det enda sättet att få information från händelsearkivet är att fylla i vyer i förväg genom att undersöka alla händelser för att fastställa det aktuella läget. Om du inte använder Event Sourcing kan du överväga om en materialiserad vy kan vara användbar. Materialiserade vyer tenderar att skräddarsys specifikt för en eller ett litet antal frågor. Om många frågor används kan materialiserade vyer leda till oacceptabla krav på lagringskapacitet och lagringskostnader.

  • Datakonsekvens. Tänk på effekten på datakonsekvensen när du genererar vyn och när du uppdaterar vyn om den här processen sker enligt ett schema. Om källdata ändras samtidigt som vyn genereras är kopian av data i vyn inte helt konsekvent med de ursprungliga data. Det maximala inaktuella fönstret är en direkt följd av uppdateringsintervallet eller händelsebearbetningsfördröjningen, så definiera den acceptabla inaktuellheten innan du väljer mellan händelsedriven, schemalagd eller manuell uppdatering.

  • Visa lagringsplats. Vyn behöver inte finnas i samma arkiv eller partition som de ursprungliga data. Du kan kombinera delmängder från några olika partitioner.

  • Återskapa vid förlust. En vy kan återskapas om den går förlorad. Om vyn är tillfällig och endast används för att förbättra frågeprestandan genom att återspegla datas aktuella tillstånd, eller för att förbättra skalbarheten, kan du lagra den i en cache eller på en mindre tillförlitlig plats.

    Men om själva uppdateringsprocessen misslyckas halvvägs – till exempel om en schemalagd förnyelseaktivitet kraschar – avgör om arbetsbelastningen ska hantera den tidigare fullständiga vyn, en delvis uppdaterad vy eller ingen vy alls förrän regenereringen har slutförts.

    Den säkraste metoden är vanligtvis atomisk publikation eller versionsbyte, där din arbetsbelastning fortsätter att fungera och använda den senaste fullständiga vyn när du skapar och validerar den nya vyn. Växla till den nya vyn när verifieringen har slutförts.

  • Beräknade kolumner. När du definierar en materialiserad vy maximerar du dess värde genom att lägga till dataobjekt eller kolumner baserat på beräkning eller omvandling av befintliga dataobjekt, på värden som skickas i frågan eller på kombinationer av dessa värden när det är lämpligt.

  • Visa indexeringen. Överväg att indexera den materialiserade vyn för att öka prestanda ytterligare om detta stöds av lagringsmekanismen. Många relationsdatabaser stöder indexering för vyer. Indexunderhåll i vyn lägger dock till omkostnader för skrivvägar under varje uppdateringscykel, så balansera vinsterna för läsprestanda mot den extra uppdateringstiden och beräkningskostnaden.

  • Åtkomstkontroll för vyer. När en materialiserad vy används för att begränsa vilka dataunderuppsättningar som är synliga för vissa konsumenter, till exempel av säkerhets- eller sekretessskäl, måste visningsarkivet tillämpa samma eller striktare åtkomstkontroller som källdata. Din uppdateringspipeline måste undanta oavsiktliga kolumner eller rader, eftersom en vy som oavsiktligt innehåller data utanför det avsedda omfånget kan exponera skyddade data.

  • Datalivscykel för vyer. Tillämpa källdatans krav på kvarhållning och borttagning för varje materialiserad vy. Sprid källborttagningar och redigeringar inom den tidsperiod som krävs och inkludera varje vy i efterlevnadsövervakningen. Mer information finns i Datastyrning och säkerhetsbaslinjer med Microsoft Purview.

  • Visa livscykelhantering. Behandla vydefinitioner som distributionsbara artefakter som hanteras via källkontroll och CI/CD-pipelines, särskilt när vyer definieras deklarativt. Utan livscykelhantering kan vydefinitioner glida mellan miljöer, vilket orsakar inkonsekvent frågebeteende i utveckling, mellanlagring och produktion.

När du ska använda det här mönstret

Använd det här mönstret i sådana här scenarier:

  • Du måste skapa vyer över data som är svåra att fråga direkt, eller där frågor måste vara mycket komplexa för att extrahera data som lagras på ett normaliserat, halvstrukturerat eller ostrukturerat sätt.
  • Du vill skapa återskapande eller tillfälliga cachelagrade projektioner som förbättrar frågeprestandan, eller som formar data som används för att konstruera dataöverföringsobjekt för ett användargränssnitt, en rapport eller en visning.
  • Du måste ha stöd för ibland anslutna eller frånkopplade scenarier där anslutningen till datalagret inte alltid är tillgänglig. Du kan cacha vyn lokalt i det här fallet.
  • Du vill förenkla frågor och exponera data för experimentering på ett sätt som inte kräver kunskap om källdataformatet. Detta görs till exempel genom att koppla samman olika tabeller i en eller flera databaser eller en eller flera domäner på NoSQL-lagringsplatser och sedan formatera informationen för att anpassa den till dess slutliga användning.
  • Du vill ge åtkomst till specifika delmängder av källdata som av säkerhets- eller sekretessskäl inte ska vara allmänt tillgängliga, öppna för ändringar eller helt exponerade för användare.
  • Du vill överbrygga olika datalager för att dra nytta av deras individuella funktioner. Du kan till exempel använda ett molnlager som är effektivt för att skriva som referensdatalager och en relationsdatabas som erbjuder bra fråge- och läsprestanda för att lagra de materialiserade vyerna.
  • När du använder mikrotjänster bör du hålla dem löst kopplade, inklusive deras datalagring. Materialiserade vyer kan hjälpa dig att konsolidera data från dina tjänster. Om materialiserade vyer inte är lämpliga i din mikrotjänstarkitektur eller ett specifikt scenario kan du överväga att ha väldefinierade gränser som överensstämmer med domändriven design (DDD) och aggregerar sina data på begäran.

Det här mönstret kanske inte är lämpligt när:

  • Datakällan är enkel och lätt att fråga.
  • Källdatan ändras mycket snabbt eller kan nås utan att använda en vy. Undvik i dessa fall omkostnaderna för bearbetning med att skapa vyer.
  • Konsekvens prioriteras högt. Vyerna kanske inte alltid överensstämmer helt med dina ursprungsdata.

Design av arbetsbelastning

En arkitekt bör utvärdera hur mönstret för Materialiserad vy kan användas i designen av deras arbetsbelastning för att uppfylla de mål och principer som beskrivs i grundpelarna i Azure Well-Architected Framework. Ett exempel:

Grundpelare Så här stöder det här mönstret pelarmål
Prestandaeffektivitet hjälper din arbetsbelastning effektivt uppfylla kraven genom optimering av skalning, data och kod. De materialiserade vyerna lagrar resultatet av komplexa beräkningar eller frågor utan att databasmotorn eller klienten behöver beräknas om för varje begäran. Den här designen minskar den totala resursförbrukningen.

- PE:08 Dataprestanda

Om detta mönster inför kompromisser inom en pelare bör du överväga dem mot målen för de andra pelarna.

Example

Överväg ett försäljningsprogram som lagrar entiteterna Order, OrderItem och Customer i Azure Table Storage. Beställningar partitioneras efter kund-ID, orderobjekt efter order-ID och kunder efter region. Dessa nycklar stöder programmets användningsåtkomstmönster, men en försäljningsrapport grupperad efter produkt måste läsa data mellan partitioner och kombinera dem i programkod.

Följande bild visar en materialiserad vy som lagrar det totala försäljningsvärdet och antalet distinkta inköpskunder för varje produkt i kategorin Elektronik. Källraderna och sammanfattningsvärdena är illustrativa, inte en fullständig indatauppsättning för de summor som visas.

Diagram som visar tabellerna Order, OrderItem och Customer tillsammans i en materialiserad försäljningssammanfattning partitionerad efter produktkategori.

En bakgrundsprocess läser de källentiteter som krävs, associerar orderobjekt med deras beställningar och kunder och aggregerar försäljning efter produkt. Varje kund räknas en gång per produkt, även om kunden har flera beställningar eller orderrader. Processen skriver resultatet till en separat sammanfattningstabell med produktkategori som PartitionKey och produkt-ID som RowKey. Den här sammanfattningstabellen är en programunderhållen projektion, inte en databasbaserad materialiserad vy.

En instrumentpanel kan sedan köra frågor mot elektronikpartitionen i stället för att upprepa läsningar och aggregeringar mellan partitioner för varje begäran. En sökning efter en produkt tillhandahåller båda nycklarna. Information om frågeprestandakonsekvenserna av dessa nycklar finns i Design för frågor.

Uppdatera sammanfattningen enligt ett schema som uppfyller rapportens godkända föråldringsfönster. Skapa och verifiera en ny version innan du publicerar den, så att läsarna fortsätter att använda den tidigare fullständiga versionen under en ombyggnad. Uppdateringen medför fortfarande läs- och aggregeringskostnader mellan partitioner, men upprepade rapportfrågor återanvänder resultatet. Ändringar i källan visas inte förrän en senare uppdatering omfattar dem.

Nästa steg

Följande mönster kan också vara relevanta när du implementerar det här mönstret:

  • CQRS-mönster (Command and Query Responsibility Segregation). Använd detta för att uppdatera informationen i en materialiserad vy genom att svara på händelser som inträffar när de underliggande datavärdena ändras.
  • Event Sourcing-mönster. Detta används tillsammans med CQRS-mönstret för att upprätthålla informationen i en materialiserad vy. När datavärdena en materialiserad vy baseras på ändringar kan systemet generera händelser som beskriver dessa ändringar och spara dem i ett händelselager.
  • Index-tabellmönster. Data i en materialiserad vy är vanligtvis organiserade efter en primär nyckel, men frågor kan behöva hämta information från den här vyn genom att undersöka data i andra fält. Använd det här mönstret för att skapa sekundära index över datauppsättningar för datalager som inte stöder interna sekundära index.