Utforma för frågor

Tabelltjänstlösningar kan vara läsintensiva, skrivintensiva eller en blandning av de två. Den här artikeln fokuserar på saker att tänka på när du utformar tabelltjänsten för att stödja läsåtgärder effektivt. Vanligtvis är en design som stöder läsåtgärder effektivt också effektiv för skrivåtgärder. Det finns dock ytterligare saker att tänka på när du utformar för att stödja skrivåtgärder, som beskrivs i artikeln Designa för dataändring.

En bra utgångspunkt för att utforma table service-lösningen så att du kan läsa data effektivt är att fråga "Vilka frågor måste mitt program köra för att hämta de data som behövs från Table-tjänsten?"

Anteckning

Med table-tjänsten är det viktigt att få designen korrekt i förväg eftersom det är svårt och dyrt att ändra den senare. I en relationsdatabas är det till exempel ofta möjligt att åtgärda prestandaproblem genom att lägga till index i en befintlig databas: det här är inte ett alternativ med tabelltjänsten.

Det här avsnittet fokuserar på de viktiga problem som du måste åtgärda när du utformar dina tabeller för frågor. Ämnena som beskrivs i det här avsnittet är:

Hur valet av PartitionKey och RowKey påverkar frågeprestanda

I följande exempel förutsätts att tabelltjänsten lagrar medarbetarentiteter med följande struktur (de flesta av exemplen utelämnar timestamp-egenskapen för tydlighetens skull):

Kolumnnamn Datatyp
PartitionKey (avdelningsnamn) Sträng
RowKey (medarbetar-ID) Sträng
FirstName Sträng
LastName Sträng
Age Integer
EmailAddress Sträng

I artikeln Översikt över Azure Table Storage beskrivs några av de viktigaste funktionerna i Azure Table-tjänsten som har direkt påverkan på utformningen av frågor. Dessa resulterar i följande allmänna riktlinjer för att utforma tabelltjänstfrågor. Observera att filtersyntaxen som används i exemplen nedan kommer från Rest-API:et för tabelltjänsten. Mer information finns i Fråga entiteter.

  • En punktfråga är den mest effektiva sökningen att använda och rekommenderas att användas för sökningar med stora volymer eller sökningar som kräver kortast svarstid. En sådan fråga kan använda indexen för att hitta en enskild entitet mycket effektivt genom att ange värden för både PartitionKey och RowKey . Exempel: $filter=(PartitionKey eq 'Sales') och (RowKey eq '2')
  • Det näst bästa är en intervallfråga som använder PartitionKey och filtrerar på ett intervall med RowKey-värden för att returnera mer än en entitet. PartitionKey-värdet identifierar en specifik partition och RowKey-värdena identifierar en delmängd av entiteterna i partitionen. Exempel: $filter=PartitionKey eq "Sales" och RowKey ge 'S' och RowKey lt 'T'
  • Det tredje bästa är en partitionsgenomsökning som använder PartitionKey och filtrerar på en annan icke-nyckelegenskap och som kan returnera mer än en entitet. PartitionKey-värdet identifierar en specifik partition och egenskapsvärdena som väljs för en delmängd av entiteterna i partitionen. Till exempel: $filter=PartitionKey eq 'Sales' and LastName eq 'Smith'
  • En tabellgenomsökning innehåller inte PartitionKey och är mycket ineffektiv eftersom den söker igenom alla partitioner som utgör tabellen i tur och ordning efter matchande entiteter. Den utför en tabellgenomsökning oavsett om filtret använder RowKey eller inte. Till exempel: $filter=LastName eq 'Jones'
  • Frågor som returnerar flera entiteter returnerar dem sorterade i ordningen PartitionKey och RowKey . Om du vill undvika att använda entiteterna i klienten väljer du en RowKey som definierar den vanligaste sorteringsordningen.

Observera att om du använder ett "eller" för att ange ett filter baserat på RowKey-värden resulterar det i en partitionsgenomsökning och behandlas inte som en intervallfråga. Därför bör du undvika frågor som använder filter som: $filter=PartitionKey eq "Sales" och (RowKey eq '121' eller RowKey eq '322')

Exempel på kod på klientsidan som använder Storage-klientbiblioteket för att köra effektiva frågor finns i:

Exempel på kod på klientsidan som kan hantera flera entitetstyper som lagras i samma tabell finns i:

Välja en lämplig PartitionKey

Valet av PartitionKey bör balansera behovet av att aktivera användningen av entitetsgrupptransaktioner (för att säkerställa konsekvens) mot kravet på att distribuera dina entiteter över flera partitioner (för att säkerställa en skalbar lösning).

I en extrem kan du lagra alla dina entiteter i en enda partition, men detta kan begränsa lösningens skalbarhet och förhindra att tabelltjänsten kan belastningsutjämningsbegäranden. I den andra ytterligheten kan du lagra en entitet per partition, vilket skulle vara mycket skalbart och som gör det möjligt för tabelltjänsten att belastningsutjämningsbegäranden, men som skulle hindra dig från att använda entitetsgrupptransaktioner.

En perfekt PartitionKey är en som gör att du kan använda effektiva frågor och som har tillräckligt med partitioner för att säkerställa att din lösning är skalbar. Vanligtvis upptäcker du att dina entiteter har en lämplig egenskap som distribuerar dina entiteter över tillräckligt många partitioner.

Anteckning

I ett system som lagrar information om användare eller anställda kan UserID till exempel vara en bra PartitionKey. Du kan ha flera entiteter som använder ett visst UserID som partitionsnyckel. Varje entitet som lagrar data om en användare grupperas i en enda partition, så dessa entiteter är tillgängliga via entitetsgrupptransaktioner, samtidigt som de är mycket skalbara.

Det finns ytterligare överväganden i valet av PartitionKey som relaterar till hur du ska infoga, uppdatera och ta bort entiteter. Mer information finns i Designa tabeller för dataändring.

Optimera frågor för tabelltjänsten

Tabelltjänsten indexerar automatiskt dina entiteter med värdena PartitionKey och RowKey i ett enda grupperat index, vilket gör att punktfrågor är de mest effektiva att använda. Det finns dock inga andra index än det i det klustrade indexet på PartitionKey och RowKey.

Många designer måste uppfylla kraven för att aktivera sökning av entiteter baserat på flera kriterier. Du kan till exempel hitta medarbetaretiteter baserat på e-post, medarbetar-ID eller efternamn. Mönstren som beskrivs i Tabelldesignmönster löser dessa typer av krav och beskriver olika sätt att kringgå det faktum att Tabelltjänsten inte tillhandahåller sekundära index:

  • Sekundärt indexmönster mellan partitioner – Lagra flera kopior av varje entitet med olika RowKey-värden (i samma partition) för att möjliggöra snabba och effektiva sökningar och alternativa sorteringsordningar med hjälp av olika RowKey-värden .
  • Sekundärt indexmönster mellan partitioner – Lagra flera kopior av varje entitet med olika RowKey-värden i separata partitioner eller i separata tabeller för att möjliggöra snabba och effektiva sökningar och alternativa sorteringsordningar med hjälp av olika RowKey-värden .
  • Mönster för indexentiteter – Underhåll indexentiteter för att möjliggöra effektiva sökningar som returnerar listor över entiteter.

Sortera data i tabelltjänsten

Tabelltjänsten returnerar entiteter sorterade i stigande ordning baserat på PartitionKey och sedan efter RowKey. Dessa nycklar är strängvärden och för att säkerställa att numeriska värden sorteras korrekt bör du konvertera dem till en fast längd och fylla på dem med nollor. Om till exempel det värde för medarbetar-ID som du använder som RowKey är ett heltalsvärde bör du konvertera medarbetar-ID 123 till 00000123.

Många program har krav på att använda data sorterade i olika ordningar: till exempel sortera anställda efter namn eller efter anslutningsdatum. Följande mönster beskriver hur du alternativa sorteringsordningar för dina entiteter:

  • Sekundärt indexmönster mellan partitioner – Lagra flera kopior av varje entitet med olika RowKey-värden (i samma partition) för att möjliggöra snabba och effektiva sökningar och alternativa sorteringsordningar med hjälp av olika RowKey-värden.
  • Sekundärt indexmönster mellan partitioner – Lagra flera kopior av varje entitet med olika RowKey-värden i separata partitioner i separata tabeller för att möjliggöra snabba och effektiva sökningar och alternativa sorteringsordningar med hjälp av olika RowKey-värden.
  • Loggslutsmönster – Hämta de n entiteter som senast lagts till i en partition med hjälp av ett RowKey-värde som sorterar i omvänd datum- och tidsordning.

Nästa steg