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.