Compartilhar via


ProductKey og PartitionKey i Azure DataTables

Jeg får ofte spørsmål om riktig bruk og definisjon av disse to begrepene innenfor DataTables i Azure. Derfor tenkte jeg at et kort blogginnlegg om dette kunne være på sin plass:

PartitionKey

Denne delen av nøkkelen handler om ytelse, og hvordan Azure kan sørge for å levere en lavest mulig responstid. Dersom en partisjon er mye brukt, så flyttes den til en en server som støtter den høyere trafikken. Om den blir stor, så flyttes den til en server med tilsvarende lagringskapasitet. Partisjoner generelt, er forskjellige for de ulike tjenestene innenfor Azure lagring:

· I Blob storage er hver enkelt blob en separat partisjon. Det betyr at blobs alltid kan få den beste throughputen systemet kan levere

· I køer er hver enkelt kø en separat partisjon

· I tabeller bestemmer du, ved å angi partisjonsnøkkel, hvordan data sameksisterer i systemet

Dette betyr med andre ord at det er du selv som er ansvarlig for ytelsen i løsningen din ved å tenke smart mht partitionkey.

Merk:

Azure lagring kan selv finne ut at den trenger å spalte opp partisjoner i såkalte “Range Partitions”. Se følgende lenke for mer informasjon:
https://msdn.microsoft.com/en-us/library/windowsazure/hh508997.aspx.

RowKey

Din RowKey (radnøkkel) er ganske enkelt din «primærnøkkel» innenfor den partisjonen som du har valgt. Sammen med PartitionKey har du dermed en unik kombinasjon for din entitet. Du kan kun ha en radnøkkel pr partisjon, men dersom du opererer med flere partisjoner, kan radnøkkelen angis om igjen.

For eksempel:

PartitionKey

RowKey

Entitet

ProduktPris

123

<Entitet som beskriver prisen>

ProduktDimensjon

123

<Entitet som beskriver mål og vekt>

ProduktPlassering

123

<Entitet som beskriver plassering av produkt på lager>

ProduktDetalj

123

<Entitet som beskriver detaljer om produktet>

Tabellen over viser kombinasjonen av ulike partisjoner for samme produkt id.

Ytelse

Det er fornuftig å tenke gjennom hvordan du bruker kombinasjonen av PartitionKey og RowKey før du skriver koden din. Ikke bare gi de en tilfeldig verdi/GUID, fordi dette har konsekvenser for ytelsen du får.

Den raskeste måten å få svar fra DataTables oppnås ved å spesifisere PartitionKey og RowKey samtidig. Ved å gjøre dette så vil DataTabellen vite hvilken partisjon den skal spørre på.

Litt mindre raskt (men fremdeles raskt nok!) er å spørre ved å spesifisere PartitionKey.

Mindre raskt er å spørre på RowKey. Ved å gjøre dette vet ikke Storage hvilken partisjon den skal starte i,  slik at den gjør en “fan out” spørring mot alle partisjoner, og dermed, potensielt flere systemer. Innenfor en partisjon er søk på PartitionKey ekstremt raskt, siden dette er en unik indeks.

Tregt: Søk på andre felter i tabellen (fordi dette spenner over flere partisjoner i søk etter egenskapene

Øvelse

La oss si at du skal lagre kunder, Ordre, og Ordrelinjer. Hva bør du velge som PartitionKey  og RowKey ?

Et “ideelt” oppsett kan se slik ut, avhengig av hvordan du ønsker å spørre etter data:

Tabell PartitionKey RowKey Kommentar
Kunde SalgsRegion KundeId Gir raske søk på region og kundens id
Ordre KundeId OrdreId Gir meg muligheten til å raskt søke opp alle ordrene til en bestemt kunde. Det går også raskt å søke opp spesifikk ordreId.
Ordrelinje OrdreId OrdrelinjeId Raskt oppslag på ordreId og ordrelinjeId

Avhengig av systemet som bygges, så er kanskje dette et bedre oppsett:

Tabell PartitionKey RowKey Kommentar
Kunde KundeId VisningsNavn Raske søk både på kundeId og visningsnavnet
Ordre KundeId OrdreId Gir meg muligheten til å raskt søke opp alle ordrene til en bestemt kunde. Det går også raskt å søke opp spesifikk ordreId.
Ordrelinje OrdreId ProduktId Raskt oppslag på ordreId og hvilket produkt som ble kjøpt

Som sagt, det å tenke gjennom løsningen og hvordan man ser for seg bruken av datatabeller er viktig. Det er også et viktig poeng at du ikke må velge enten/eller! Det er helt normalt å denormalisere sine data og lagre de dobbelt under ulike formater for å støtte flere spørringsalternativer!

Det finnes en siste “index”!

Nemlig! Tabellnavnet er også en index! La oss kikke på eksemplet ordre-ordrelinje en gang til:

Det å ha en kundetabell som inneholder alle kunder er interessant å søke etter innenfor den typen data, men å ha en ordretabell som inneholder alle ordre for alle kunder er kanskje ikke en ideell løsning. En tanke er derfor å lage en ordretabell pr.Kunde? Dersom du gjør dette, så kan du veldig raskt spørre etter ordre Ider (tabellnavnet) og innenfor ordretabellen kan du da legge flere detaljer i PartitionKey og PrimaryKey.

Og.. ENDA en: Du kan faktisk også splitte data over flere lagringskontoer for å få nok en “partisjon”

Konklusjon

Tenk godt gjennom PartitionKey og RowKey slik at de gir mening for den løsningen eller forretningsdomenet. Da oppnår du raskere spørringer og en effektiv bruk av DataTables i lengden.