Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Hoewel databases zonder schema's, zoals Azure Cosmos DB, het eenvoudig maken om ongestructureerde en semi-gestructureerde gegevens op te slaan en op te vragen, kunt u nadenken over uw gegevensmodel om de prestaties, schaalbaarheid en kosten te optimaliseren.
Hoe worden gegevens opgeslagen? Hoe haalt uw toepassing gegevens op en voert u er query's op uit? Is uw toepassing leesintensief of schrijfintensief?
Na het lezen van dit artikel kunt u de volgende vragen beantwoorden:
- Wat is gegevensmodellering en waarom kan het mij schelen?
- Hoe verschilt het modelleren van gegevens in Azure Cosmos DB van een relationele database?
- Hoe drukt u gegevensrelaties uit in een niet-relationele database?
- Wanneer kan ik gegevens insluiten en wanneer maak ik een koppeling naar gegevens?
Getallen in JSON
Azure Cosmos DB slaat documenten op in JSON, dus het is belangrijk om te bepalen of getallen moeten worden geconverteerd naar tekenreeksen voordat ze in JSON worden opgeslagen. Converteer alle getallen naar een String als ze de grenzen van dubbele precisienummers kunnen overschrijden, zoals gedefinieerd door Institute of Electrical and Electronics Engineers (IEEE) 754 binary64. In de JSON-specificatie wordt uitgelegd waarom het gebruik van getallen buiten deze grens een slechte gewoonte is vanwege interoperabiliteitsproblemen. Deze problemen zijn met name relevant voor de partitiesleutelkolom omdat deze onveranderbaar is en gegevensmigratie later moet worden gewijzigd.
Gegevens insluiten
Wanneer u gegevens modelleert in Azure Cosmos DB, behandelt u uw entiteiten als zelfstandige items die worden weergegeven als JSON-documenten .
Laten we eerst eens kijken hoe we gegevens in een relationele database kunnen modelleren. In het volgende voorbeeld ziet u hoe een persoon kan worden opgeslagen in een relationele database.
De strategie, bij het werken met relationele databases, is het normaliseren van al uw gegevens. Het normaliseren van uw gegevens omvat doorgaans het nemen van een entiteit, zoals een persoon, en het opsplitsen ervan in afzonderlijke onderdelen. In het voorbeeld kan een persoon meerdere records met contactgegevens en meerdere adresrecords hebben. U kunt contactgegevens verder opsplitsen door algemene velden zoals type te extraheren. Dezelfde benadering is van toepassing op adressen. Elke record kan worden geclassificeerd als Thuisgebruik of Zakelijk.
Het uitgangspunt bij het normaliseren van gegevens is om te voorkomen dat redundante gegevens in elke record worden opgeslagen en in plaats daarvan verwijzen naar gegevens. Als u in dit voorbeeld een persoon met al hun contactgegevens en adressen wilt lezen, moet u JOINS gebruiken om uw gegevens effectief op te stellen (of te denormaliseren) tijdens runtime.
SELECT p.FirstName, p.LastName, a.City, cd.Detail
FROM Person p
JOIN ContactDetail cd ON cd.PersonId = p.Id
JOIN ContactDetailType cdt ON cdt.Id = cd.TypeId
JOIN Address a ON a.PersonId = p.Id
Voor het bijwerken van de contactgegevens en adressen van één persoon zijn schrijfbewerkingen vereist voor veel afzonderlijke tabellen.
Laten we nu eens kijken hoe we dezelfde gegevens modelleren als een zelfstandige entiteit in Azure Cosmos DB.
{
"id": "1",
"firstName": "Thomas",
"lastName": "Andersen",
"addresses": [
{
"line1": "100 Some Street",
"line2": "Unit 1",
"city": "Seattle",
"state": "WA",
"zip": 98012
}
],
"contactDetails": [
{"email": "thomas@andersen.com"},
{"phone": "+1 555 555-5555", "extension": 5555}
]
}
Met deze methode hebben we de persoonsrecord gedenormaliseerd door alle informatie over deze persoon, zoals contactgegevens en adressen, in te sluiten in één JSON-document . Bovendien hebben we, omdat we niet beperkt zijn tot een vast schema, de flexibiliteit om dingen te doen zoals het hebben van contactgegevens in volledig verschillende vormen.
Het ophalen van een volledige persoonsrecord uit de database is nu één leesbewerking voor één container voor één item. Het bijwerken van de contactgegevens en adressen van een persoonsrecord is ook één schrijfbewerking voor één item.
Het denormaliseren van gegevens kan het aantal query's verminderen en uw toepassing bijwerken om algemene bewerkingen te voltooien.
Wanneer moet ik insluiten?
Gebruik in het algemeen ingesloten gegevensmodellen wanneer:
- Er zijn ingesloten relaties tussen entiteiten.
- Er zijn een-op-weinig relaties tussen entiteiten.
- De gegevens worden zelden gewijzigd.
- De gegevens groeien niet zonder gebonden.
- De gegevens worden regelmatig samen opgevraagd.
Notitie
Normaal gesproken gedenormaliseerde gegevensmodellen bieden betere leesprestaties .
Wanneer niet insluiten
Hoewel de vuistregel in Azure Cosmos DB is om alles te denormaliseren en alle gegevens in één item in te sluiten, kan deze aanpak leiden tot situaties die moeten worden vermeden.
Neem dit JSON-fragment.
{
"id": "1",
"name": "What's new in the coolest Cloud",
"summary": "A blog post by someone real famous",
"comments": [
{"id": 1, "author": "anon", "comment": "something useful, I'm sure"},
{"id": 2, "author": "bob", "comment": "wisdom from the interwebs"},
…
{"id": 100001, "author": "jane", "comment": "and on we go ..."},
…
{"id": 1000000001, "author": "angry", "comment": "blah angry blah angry"},
…
{"id": ∞ + 1, "author": "bored", "comment": "oh man, will this ever end?"},
]
}
Dit voorbeeld kan zijn hoe een postentiteit met ingesloten opmerkingen eruit zou zien als we een typische blog of cms (Content Management System) modelleren. Het probleem met dit voorbeeld is dat de opmerkingenmatrix niet afhankelijk is, wat betekent dat er geen (praktische) limiet is voor het aantal opmerkingen dat één bericht kan hebben. Dit ontwerp kan problemen veroorzaken omdat de grootte van het item oneindig groot kan worden, dus vermijd het.
Naarmate de itemgrootte toeneemt, worden het verzenden, lezen en bijwerken van de gegevens op schaal moeilijker.
In dit geval is het beter om rekening te houden met het volgende gegevensmodel.
Post item:
{
"id": "1",
"name": "What's new in the coolest Cloud",
"summary": "A blog post by someone real famous",
"recentComments": [
{"id": 1, "author": "anon", "comment": "something useful, I'm sure"},
{"id": 2, "author": "bob", "comment": "wisdom from the interwebs"},
{"id": 3, "author": "jane", "comment": "....."}
]
}
Comment items:
[
{"id": 4, "postId": "1", "author": "anon", "comment": "more goodness"},
{"id": 5, "postId": "1", "author": "bob", "comment": "tails from the field"},
...
{"id": 99, "postId": "1", "author": "angry", "comment": "blah angry blah angry"},
{"id": 100, "postId": "2", "author": "anon", "comment": "yet more"},
...
{"id": 199, "postId": "2", "author": "bored", "comment": "will this ever end?"}
]
Dit model heeft een item voor elke opmerking met een eigenschap die de post-id bevat. Met dit model kunnen berichten een willekeurig aantal opmerkingen bevatten en efficiënt groeien. Gebruikers die meer willen zien dan de meest recente opmerkingen, voeren een query uit op deze container die de postId doorgeeft. Dit moet de partitiesleutel voor de opmerkingencontainer zijn.
Een ander geval waarbij het insluiten van gegevens geen goed idee is, is wanneer de ingesloten gegevens vaak worden gebruikt in items en vaak worden gewijzigd.
Neem dit JSON-fragment.
{
"id": "1",
"firstName": "Thomas",
"lastName": "Andersen",
"holdings": [
{
"numberHeld": 100,
"stock": { "symbol": "zbzb", "open": 1, "high": 2, "low": 0.5 }
},
{
"numberHeld": 50,
"stock": { "symbol": "xcxc", "open": 89, "high": 93.24, "low": 88.87 }
}
]
}
Dit voorbeeld kan de aandelenportefeuille van een persoon vertegenwoordigen. We hebben ervoor gekozen om de voorraadgegevens in te sluiten in elk portfoliodocument. In een omgeving waarin gerelateerde gegevens regelmatig worden gewijzigd, betekent dit dat u elke portfolio voortdurend bijwerkt. Met behulp van een voorbeeld van een beurstoepassing werkt u elk portfolio-item bij telkens wanneer een aandelen wordt verhandeld.
Aandelen zbzb kunnen honderden keren in één dag worden verhandeld en duizenden gebruikers kunnen in hun portefeuilles hebben zbzb . Met een gegevensmodel zoals het voorbeeld moet het systeem duizenden portfoliodocumenten meerdere keren per dag bijwerken, wat niet goed schaalt.
Verwijzingsgegevens
Het insluiten van gegevens werkt in veel gevallen goed, maar er zijn scenario's waarin het denormaliseren van uw gegevens meer problemen veroorzaakt dan het waard is. Wat kun je doen?
U kunt relaties tussen entiteiten in documentdatabases maken, niet alleen in relationele databases. In een documentdatabase kan één item informatie bevatten die verbinding maakt met gegevens in andere documenten. Azure Cosmos DB is niet ontworpen voor complexe relaties zoals relaties in relationele databases, maar eenvoudige koppelingen tussen items zijn mogelijk en kunnen nuttig zijn.
In de JSON gebruiken we het voorbeeld van een aandelenportefeuille van eerder, maar deze keer verwijzen we naar het aandelenitem in de portfolio in plaats van het insluiten ervan. Op deze manier is wanneer het voorraaditem de hele dag regelmatig verandert, het enige item dat moet worden bijgewerkt, het document met één voorraad is.
Person document:
{
"id": "1",
"firstName": "Thomas",
"lastName": "Andersen",
"holdings": [
{ "numberHeld": 100, "stockId": 1},
{ "numberHeld": 50, "stockId": 2}
]
}
Stock documents:
{
"id": "1",
"symbol": "zbzb",
"open": 1,
"high": 2,
"low": 0.5,
"vol": 11970000,
"mkt-cap": 42000000,
"pe": 5.89
},
{
"id": "2",
"symbol": "xcxc",
"open": 89,
"high": 93.24,
"low": 88.87,
"vol": 2970200,
"mkt-cap": 1005000,
"pe": 75.82
}
Een nadeel van deze aanpak is dat uw toepassing meerdere databaseaanvragen moet indienen om informatie over elk aandeel in de portfolio van een persoon op te halen. Dit ontwerp maakt het schrijven van gegevens sneller, omdat er vaak updates plaatsvinden. Het maakt het lezen of opvragen van gegevens echter langzamer, wat minder belangrijk is voor dit systeem.
Notitie
Genormaliseerde gegevensmodellen kunnen meer retouren naar de server vereisen.
Hoe zit het met foreign keys?
Omdat er geen concept van een beperking is, zoals een refererende sleutel, controleert de database geen relaties tussen documenten; deze koppelingen zijn effectief 'zwak'. Als u ervoor wilt zorgen dat de gegevens waarnaar een item verwijst, daadwerkelijk bestaan, moet u deze stap uitvoeren in uw toepassing of met behulp van triggers aan de serverzijde of opgeslagen procedures in Azure Cosmos DB.
Wanneer te verwijzen
Gebruik over het algemeen genormaliseerde gegevensmodellen wanneer:
- Een-op-veel-relaties vertegenwoordigen.
- Veel-op-veel-relaties vertegenwoordigen.
- Gerelateerde gegevens worden regelmatig gewijzigd.
- Gegevens waarnaar wordt verwezen, kunnen onbegrensd zijn.
Notitie
Normaliseren biedt doorgaans betere schrijfprestaties .
Waar zet ik de relatie?
De groei van de relatie helpt bepalen in welk item de verwijzing moet worden opgeslagen.
Als we de JSON observeren die uitgevers en boeken modelleert.
Publisher document:
{
"id": "mspress",
"name": "Microsoft Press",
"books": [ 1, 2, 3, ..., 100, ..., 1000]
}
Book documents:
{"id": "1", "name": "Azure Cosmos DB 101" }
{"id": "2", "name": "Azure Cosmos DB for RDBMS Users" }
{"id": "3", "name": "Taking over the world one JSON doc at a time" }
...
{"id": "100", "name": "Learn about Azure Cosmos DB" }
...
{"id": "1000", "name": "Deep Dive into Azure Cosmos DB" }
Als het aantal boeken per uitgever klein is en de groei beperkt is, kan het opslaan van de boekreferentie in het uitgeversitem nuttig zijn. Als het aantal boeken per uitgever echter niet afhankelijk is, zou dit gegevensmodel leiden tot veranderlijke, groeiende matrices, zoals in het voorbeelduitgeverdocument.
Het veranderen van de structuur resulteert in een model dat dezelfde gegevens vertegenwoordigt, maar grote muteerbare verzamelingen vermijdt.
Publisher document:
{
"id": "mspress",
"name": "Microsoft Press"
}
Book documents:
{"id": "1","name": "Azure Cosmos DB 101", "pub-id": "mspress"}
{"id": "2","name": "Azure Cosmos DB for RDBMS Users", "pub-id": "mspress"}
{"id": "3","name": "Taking over the world one JSON doc at a time", "pub-id": "mspress"}
...
{"id": "100","name": "Learn about Azure Cosmos DB", "pub-id": "mspress"}
...
{"id": "1000","name": "Deep Dive into Azure Cosmos DB", "pub-id": "mspress"}
In dit voorbeeld bevat het publisher-document geen niet-gebonden verzameling meer. In plaats daarvan bevat elk boekdocument een verwijzing naar de uitgever.
Hoe kan ik veel-op-veel-relaties modelleren?
In een relationele database worden veel-op-veel-relaties vaak gemodelleerd met jointabellen. Deze relaties voegen records uit andere tabellen samen.
U bent misschien geneigd om hetzelfde te repliceren met behulp van documenten en een gegevensmodel te produceren dat er ongeveer als volgt uitziet.
Author documents:
{"id": "a1", "name": "Thomas Andersen" }
{"id": "a2", "name": "William Wakefield" }
Book documents:
{"id": "b1", "name": "Azure Cosmos DB 101" }
{"id": "b2", "name": "Azure Cosmos DB for RDBMS Users" }
{"id": "b3", "name": "Taking over the world one JSON doc at a time" }
{"id": "b4", "name": "Learn about Azure Cosmos DB" }
{"id": "b5", "name": "Deep Dive into Azure Cosmos DB" }
Joining documents:
{"authorId": "a1", "bookId": "b1" }
{"authorId": "a2", "bookId": "b1" }
{"authorId": "a1", "bookId": "b2" }
{"authorId": "a1", "bookId": "b3" }
Deze methode werkt, maar het laden van een auteur met hun boeken of een boek met de auteur vereist altijd ten minste twee extra databasequery's. Eén query naar het samenvoegingsitem en vervolgens een andere query om het werkelijke item dat wordt toegevoegd, op te halen.
Waarom zou je deze join niet helemaal weglaten als hij slechts twee stukjes gegevens aan elkaar lijmt? Bekijk het volgende voorbeeld.
Author documents:
{"id": "a1", "name": "Thomas Andersen", "books": ["b1", "b2", "b3"]}
{"id": "a2", "name": "William Wakefield", "books": ["b1", "b4"]}
Book documents:
{"id": "b1", "name": "Azure Cosmos DB 101", "authors": ["a1", "a2"]}
{"id": "b2", "name": "Azure Cosmos DB for RDBMS Users", "authors": ["a1"]}
{"id": "b3", "name": "Learn about Azure Cosmos DB", "authors": ["a1"]}
{"id": "b4", "name": "Deep Dive into Azure Cosmos DB", "authors": ["a2"]}
Met dit model kunt u gemakkelijk zien welke boeken een auteur heeft geschreven door het document te bekijken. U kunt ook zien welke auteurs een boek hebben geschreven door het boekdocument te controleren. U hoeft geen afzonderlijke jointabel te gebruiken of extra query's te maken. Dit model maakt het sneller en eenvoudiger voor uw toepassing om de gegevens op te halen die nodig zijn.
Hybride gegevensmodellen
We verkennen het insluiten (of denormaliseren) en verwijzen naar (of normaliseren) gegevens. Elke aanpak biedt voordelen en omvat compromissen.
Het hoeft niet altijd te zijn of. Aarzel niet om dingen een beetje te combineren.
Op basis van de specifieke gebruikspatronen en workloads van uw toepassing kan het zinvol zijn om ingesloten en verwezen gegevens te combineren. Deze aanpak kan toepassingslogica vereenvoudigen, retouren van servers verminderen en goede prestaties behouden.
Houd rekening met de volgende JSON.
Author documents:
{
"id": "a1",
"firstName": "Thomas",
"lastName": "Andersen",
"countOfBooks": 3,
"books": ["b1", "b2", "b3"],
"images": [
{"thumbnail": "https://....png"}
{"profile": "https://....png"}
{"large": "https://....png"}
]
},
{
"id": "a2",
"firstName": "William",
"lastName": "Wakefield",
"countOfBooks": 1,
"books": ["b1"],
"images": [
{"thumbnail": "https://....png"}
]
}
Book documents:
{
"id": "b1",
"name": "Azure Cosmos DB 101",
"authors": [
{"id": "a1", "name": "Thomas Andersen", "thumbnailUrl": "https://....png"},
{"id": "a2", "name": "William Wakefield", "thumbnailUrl": "https://....png"}
]
},
{
"id": "b2",
"name": "Azure Cosmos DB for RDBMS Users",
"authors": [
{"id": "a1", "name": "Thomas Andersen", "thumbnailUrl": "https://....png"},
]
}
Hier hebben we (meestal) het ingesloten model gevolgd, waarbij gegevens van andere entiteiten zijn ingesloten in het document op het hoogste niveau, maar naar andere gegevens wordt verwezen.
Als u het boekdocument bekijkt, zien we een paar interessante velden wanneer we kijken naar de matrix met auteurs. Er is een id veld dat het veld is dat we gebruiken om terug te verwijzen naar een auteurdocument, standaardpraktijk in een genormaliseerd model, maar dan hebben name we ook en thumbnailUrl. We konden alleen de id toepassing gebruiken en de toepassing alle aanvullende informatie laten ophalen die nodig is uit het bijbehorende auteuritem met behulp van de 'koppeling'. Aangezien in de toepassing echter de naam van de auteur en een miniatuurafbeelding voor elk boek worden weergegeven, vermindert het denormaliseren van sommige gegevens van de auteur het aantal retouren per server per boek in een lijst.
Als de naam van de auteur verandert of de foto bijwerkt, moet u elk boek bijwerken dat ze hebben gepubliceerd. Voor deze toepassing, ervan uitgaande dat auteurs hun namen zelden wijzigen, is dit compromis een acceptabel ontwerpbesluit.
In het voorbeeld zijn er vooraf berekende cumulatieve waarden om dure verwerking te besparen tijdens een leesbewerking. In het voorbeeld zijn sommige gegevens die zijn ingesloten in het auteuritem gegevens die tijdens runtime worden berekend. Telkens wanneer een nieuw boek wordt gepubliceerd, wordt een boekitem gemaakt en wordt het veld countOfBooks ingesteld op een berekende waarde op basis van het aantal boekdocumenten dat voor een bepaalde auteur bestaat. Deze optimalisatie zou goed zijn in leesintensieve systemen, waar we het ons kunnen veroorloven om berekeningen op schrijfbewerkingen uit te voeren om leesbewerkingen te optimaliseren.
De mogelijkheid om een model met vooraf berekende velden te hebben, wordt mogelijk gemaakt omdat Azure Cosmos DB ondersteuning biedt voor transacties met meerdere documenten. Veel NoSQL-winkels kunnen geen transacties uitvoeren in documenten en daarom pleiten voor ontwerpbeslissingen zoals altijd alles insluiten vanwege deze beperking. Met Azure Cosmos DB kunt u triggers aan de serverzijde of opgeslagen procedures gebruiken die boeken invoegen en auteurs bijwerken, allemaal binnen een ACID-transactie. Nu hoeft u niet alles in één item in te sluiten om er zeker van te zijn dat uw gegevens consistent blijven.
Onderscheid maken tussen verschillende itemtypen
In sommige scenario's wilt u mogelijk verschillende itemtypen in dezelfde verzameling combineren; deze ontwerpkeuze is meestal het geval wanneer u meerdere gerelateerde documenten in dezelfde partitie wilt hebben. U kunt bijvoorbeeld zowel boeken als boekrecensies in dezelfde collectie plaatsen en partitioneren door bookId. In een dergelijke situatie wilt u meestal een veld toevoegen aan uw documenten die hun type identificeren om ze te onderscheiden.
Book documents:
{
"id": "b1",
"name": "Azure Cosmos DB 101",
"bookId": "b1",
"type": "book"
}
Review documents:
{
"id": "r1",
"content": "This book is awesome",
"bookId": "b1",
"type": "review"
}
{
"id": "r2",
"content": "Best book ever!",
"bookId": "b1",
"type": "review"
}
Gegevensmodellering voor Analytische opslag van Azure Synapse Link en Azure Cosmos DB
Azure Synapse Link voor Azure Cosmos DB is een cloudeigen HTAP-mogelijkheid (Hybrid Transactional and Analytical Processing) waarmee u bijna realtime analyses kunt uitvoeren op operationele gegevens in Azure Cosmos DB. Azure Synapse Link maakt een naadloze integratie tussen Azure Cosmos DB en Azure Synapse Analytics.
Deze integratie vindt plaats via analytische opslag van Azure Cosmos DB, een kolomweergave van uw transactionele gegevens die grootschalige analyses mogelijk maken zonder dat dit van invloed is op uw transactionele workloads. Met de analytische opslag kunt u snelle en betaalbare query's uitvoeren op grote gegevenssets. U hoeft de gegevens niet te kopiëren of u hoeft zich zorgen te maken over het vertragen van uw hoofddatabase. Wanneer u analytische opslag voor een container inschakelt, wordt elke wijziging die u in uw gegevens aanbrengt, bijna direct gekopieerd naar de analytische opslag. U hoeft geen Wijzigingenfeed in te stellen of ETL-taken (Extract, Transform and Load) uit te voeren. Het systeem houdt beide winkels gesynchroniseerd voor u.
Met Azure Synapse Link kunt u nu rechtstreeks verbinding maken met uw Azure Cosmos DB-containers vanuit Azure Synapse Analytics en toegang krijgen tot de analytische opslag, zonder kosten voor aanvraageenheden (aanvraageenheden). Azure Synapse Analytics ondersteunt momenteel Azure Synapse Link met Synapse Apache Spark en serverloze SQL-pools. Als u een wereldwijd gedistribueerd Azure Cosmos DB-account hebt nadat u analytische opslag voor een container hebt ingeschakeld, is dit beschikbaar in alle regio's voor dat account.
Automatische schemadeductie van analytische opslag
Transactionele opslag van Azure Cosmos DB is rijgeoriënteerde semi-gestructureerde gegevens, terwijl analytische opslag gebruikmaakt van een kolom- en gestructureerde indeling. Deze conversie wordt automatisch uitgevoerd voor klanten met behulp van de schemadeductieregels voor de analytische opslag. Er zijn limieten in het conversieproces: het maximum aantal geneste niveaus, het maximum aantal eigenschappen, niet-ondersteunde gegevenstypen en meer.
Notitie
In de context van analytische opslag beschouwen we de volgende structuren als eigenschap:
- JSON-elementen of tekenreeks-waardeparen gescheiden door een
:" - JSON-objecten, gescheiden door
{en} - JSON-matrices, gescheiden door
[en]
U kunt het effect van de schemadeductieconversies minimaliseren en uw analytische mogelijkheden maximaliseren met behulp van de volgende technieken.
Normalisatie
Normalisatie wordt minder relevant omdat u met Azure Synapse Link containers kunt koppelen met behulp van T-SQL of Spark SQL. De verwachte voordelen van normalisatie zijn:
- Kleinere gegevensvoetafdruk in zowel transactionele als analytische opslag.
- Kleinere transacties.
- Minder eigenschappen per document.
- Gegevensstructuren met minder geneste niveaus.
Door minder eigenschappen en minder niveaus in uw gegevens te hebben, kunnen analytische query's sneller worden uitgevoerd. Het helpt er ook voor te zorgen dat alle delen van uw gegevens zijn opgenomen in de analytische opslag. Zoals beschreven in het artikel over regels voor automatische schemadeductie, zijn er limieten voor het aantal niveaus en eigenschappen dat wordt weergegeven in de analytische opslag.
Een andere belangrijke factor voor normalisatie is dat serverloze SQL-pools in Azure Synapse resultatensets ondersteunen met maximaal 1000 kolommen en dat het beschikbaar maken van geneste kolommen ook telt voor die limiet. Met andere woorden, zowel analytische opslag als Serverloze Synapse SQL-pools hebben een limiet van 1000 eigenschappen.
Maar wat te doen sinds denormalisatie is een belangrijke gegevensmodelleringstechniek voor Azure Cosmos DB? Het antwoord is dat u de juiste balans moet vinden voor uw transactionele en analytische workloads.
Partitiesleutel
De Azure Cosmos DB-partitiesleutel (PK) wordt niet gebruikt in de analytische opslag. En nu kunt u aangepaste partitionering van analytische opslag gebruiken om kopieën van analytische opslag te maken met behulp van pk's die u wilt gebruiken. Vanwege deze isolatie kunt u een PK voor uw transactionele gegevens kiezen met de focus op gegevensopname en puntleesbewerkingen, terwijl query's tussen partities kunnen worden uitgevoerd met Azure Synapse Link. Laten we een voorbeeld bekijken:
In een hypothetisch globaal IoT-scenario fungeert als een goede partitiesleutel omdat device id alle apparaten een vergelijkbaar volume aan gegevens genereren, waardoor problemen met hete partities worden voorkomen. Maar als u de gegevens van meer dan één apparaat wilt analyseren, zoals 'alle gegevens van gisteren' of 'totalen per stad', hebt u mogelijk problemen omdat deze query's meerdere partitiequery's zijn. Deze query's kunnen uw transactionele prestaties schaden, omdat ze een deel van uw doorvoer gebruiken in aanvraageenheden om uit te voeren. Maar met Azure Synapse Link kunt u deze analytische query's zonder kosten voor aanvraageenheden uitvoeren. Kolomindeling voor analytische opslag is geoptimaliseerd voor analytische query's en Azure Synapse Link biedt ondersteuning voor geweldige prestaties met Azure Synapse Analytics-runtimes.
Namen van gegevenstypen en eigenschappen
In het artikel met regels voor automatische schemadeductie wordt vermeld wat de ondersteunde gegevenstypen zijn. Hoewel Azure Synapse-runtimes ondersteunde gegevenstypen anders kunnen verwerken, blokkeren niet-ondersteunde gegevenstypen de weergave in de analytische opslag. Een voorbeeld is: Wanneer u DateTime-tekenreeksen gebruikt die voldoen aan de ISO 8601 UTC-standaard, vertegenwoordigt Spark-pools in Azure Synapse deze kolommen als string en sql-serverloze pools in Azure Synapse vertegenwoordigt deze kolommen als varchar(8000).
Een andere uitdaging is dat Azure Synapse Spark niet alle tekens accepteert. Hoewel witruimten worden geaccepteerd, worden tekens zoals dubbele punt, accent grave en komma niet geaccepteerd. Stel dat uw item een eigenschap heeft met de naam Voornaam, Achternaam. Deze eigenschap wordt weergegeven in de analytische opslag en de serverloze Synapse SQL-pool kan deze zonder problemen lezen. Maar omdat het zich in de analytische opslag bevindt, kan Azure Synapse Spark geen gegevens lezen uit de analytische opslag, inclusief alle andere eigenschappen. Aan het einde van de dag kunt u Azure Synapse Spark niet gebruiken wanneer u één eigendom heeft dat gebruik maakt van de niet-ondersteunde tekens in zijn naam.
Gegevens platmaken
Elke eigenschap op het hoogste niveau van uw Azure Cosmos DB-gegevens wordt een kolom in de analytische opslag. Eigenschappen in geneste objecten of matrices worden opgeslagen als JSON in de analytische opslag, waardoor de structuur behouden blijft. Geneste structuren vereisen extra verwerking door de runtimes van Azure Synapse om de gegevens in een vlak format te krijgen, wat een uitdaging kan zijn in big data-situaties.
Het item heeft slechts twee kolommen in de analytische opslag en idcontactDetails. Alle andere gegevens, emailen phone, vereisen extra verwerking via SQL-functies om afzonderlijk te worden gelezen.
{
"id": "1",
"contactDetails": [
{"email": "thomas@andersen.com"},
{"phone": "+1 555 555-5555"}
]
}
Het item heeft drie kolommen in de analytische opslag, id, en emailphone. Alle gegevens zijn rechtstreeks toegankelijk als kolommen.
{
"id": "1",
"email": "thomas@andersen.com",
"phone": "+1 555 555-5555"
}
Gegevenslagen
Met Azure Synapse Link kunt u de kosten verlagen vanuit de volgende perspectieven:
- Minder query's die worden uitgevoerd in uw transactionele database.
- Een PK die is geoptimaliseerd voor gegevensinvoer en puntlezingen, waardoor de gegevensvoetafdruk, hete partitiescenario's en partitiesplitsingen worden verminderd.
- Gegevenslagen omdat analytische time-to-live (attl) onafhankelijk is van transactionele time-to-live (tttl). U kunt uw transactionele gegevens enkele dagen, weken, maanden bewaren en de gegevens in de analytische opslag jarenlang of voor altijd bewaren. Kolomindeling voor analytische opslag zorgt voor een natuurlijke gegevenscompressie, van 50% tot 90%. En de kosten per GB zijn ongeveer 10% van de werkelijke prijs van een transactionele opslag. Zie het overzicht van analytische opslag voor meer informatie over de huidige back-upbeperkingen.
- Er worden geen ETL-taken uitgevoerd in uw omgeving, wat betekent dat u er geen aanvraageenheden voor hoeft toe te wijzen.
Gecontroleerde redundantie
Deze techniek is een goed alternatief voor situaties waarin een gegevensmodel al bestaat en niet kan worden gewijzigd. Het huidige gegevensmodel werkt niet goed met analytische opslag. Dit voordeel bestaat omdat analytische opslag regels bevat waarmee wordt beperkt hoeveel niveaus u gegevens kunt nesten en hoeveel eigenschappen u in elk document kunt hebben. Als uw gegevens te complex zijn of te veel velden bevatten, worden bepaalde belangrijke gegevens mogelijk niet opgenomen in de analytische opslag. Als dit scenario uw geval is, kunt u azure Cosmos DB-wijzigingenfeed gebruiken om uw gegevens te repliceren naar een andere container, waarbij u de vereiste transformaties toepast voor een gebruiksvriendelijk gegevensmodel van Azure Synapse Link. Laten we een voorbeeld bekijken:
Scenario
Container CustomersOrdersAndItems wordt gebruikt voor het opslaan van on-line orders, inclusief klant- en itemsgegevens: factureringsadres, leveringsadres, leveringsmethode, leveringsstatus, prijs van artikelen, enzovoort. Alleen de eerste 1000 eigenschappen worden weergegeven en belangrijke informatie wordt niet opgenomen in de analytische opslag, waardoor het gebruik van Azure Synapse Link wordt geblokkeerd. De container heeft petabytes aan records, het is niet mogelijk om de toepassing te wijzigen en de gegevens opnieuw te modelleren.
Een ander aspect van het probleem is het grote gegevensvolume. Miljarden rijen worden voortdurend gebruikt door de analyseafdeling, wat voorkomt dat ze tttl gebruiken voor oude gegevensverwijdering. Het onderhouden van de volledige gegevensgeschiedenis in de transactionele database vanwege analytische behoeften dwingt hen om de inrichting van aanvraageenheden voortdurend te verhogen, wat van invloed is op de kosten. Transactionele en analytische workloads concurreren tegelijkertijd voor dezelfde resources.
Wat kun je doen?
Oplossing met wijzigingenfeed
- Het technische team heeft besloten om wijzigingenfeed te gebruiken om drie nieuwe containers te vullen:
Customers,OrdersenItems. Met Wijzigingenfeed worden de gegevens genormaliseerd en afgevlakt. Overbodige informatie wordt verwijderd uit het gegevensmodel en elke container heeft bijna 100 eigenschappen, waardoor gegevensverlies wordt voorkomen als gevolg van automatische schemadeductielimieten. - Voor deze nieuwe containers is analytische opslag ingeschakeld en de analyseafdeling gebruikt Synapse Analytics om de gegevens te lezen. Dit vermindert het gebruik van aanvraageenheden omdat analytische query's worden uitgevoerd in Synapse Apache Spark en serverloze SQL-pools.
- Container
CustomersOrdersAndItemsheeft nu time-to-live (TTL) ingesteld om alleen gegevens zes maanden te bewaren, waardoor het gebruik van andere aanvraageenheden kan worden verminderd, omdat er minimaal één aanvraageenheid per GB in Azure Cosmos DB is. Minder gegevens, minder aanvraageenheden.
Belangrijke punten
Het grootste voordeel van dit artikel is dat gegevensmodellering in een schemavrij scenario net zo belangrijk is als ooit.
Net zoals er geen enkele manier is om een stukje gegevens op een scherm weer te geven, is er geen enkele manier om uw gegevens te modelleren. U moet inzicht hebben in uw toepassing en hoe deze de gegevens produceert, verbruikt en verwerkt. Door de hier gepresenteerde richtlijnen toe te passen, kunt u een model maken dat voldoet aan de onmiddellijke behoeften van uw toepassing. Wanneer uw toepassing verandert, kunt u de flexibiliteit van een database zonder schema gebruiken om uw gegevensmodel eenvoudig aan te passen en te ontwikkelen.