Data og filer

Azure Table Storage og Blob Storage: hvad bruger man hvornår?

Table Storage gemmer enkle, strukturerede poster. Blob Storage gemmer selve filerne. De løser forskellige problemer, og et godt system bruger ofte begge – uden at gøre nogen af dem til en SQL-database.

Det korte valg

Vælg Table Storage til

Enkle poster, der normalt findes via en kendt virksomhed, bruger eller anden partition og en unik nøgle. Eksempelvis jobstatus, hændelser eller lette opslagstabeller.

Vælg Blob Storage til

PDF'er, billeder, videoer, eksportfiler, backups og andre tekst- eller binærfiler. Gem filens metadata i databasen, men filens bytes som en blob.

Vælg noget andet, når: Data har relationer, joins, mange skiftende søgekriterier eller tung rapportering. Her er SQL ofte et bedre valg. Firestore kan passe bedre, når en klientapp skal arbejde direkte med dokumentdata og realtime-opdateringer.

Table Storage: design efter de forespørgsler, I faktisk bruger

Hver entity har en PartitionKey og en RowKey. Kombinationen er unik og udgør det primære indeks. Et opslag med begge nøgler er effektivt; en søgning uden PartitionKey kan ende med at scanne hele tabellen.

  • PartitionKey: Gruppér data, der oftest læses eller ændres sammen – fx virksomhedens ID.
  • RowKey: Brug en stabil, unik nøgle inden for partitionen – fx opgavens ID.
  • Undgå én varm partition: En global nøgle til al trafik kan begrænse skalering.
  • Accepter begrænsningen: Table Storage har ikke joins eller frie sekundære indekser. Hvis mange felter skal kunne søges, bør datalageret genovervejes.
TypeScript: gem en entity med managed identity
import { DefaultAzureCredential } from "@azure/identity";
import { TableClient } from "@azure/data-tables";

const client = new TableClient(
  `https://${({}).STORAGE_ACCOUNT}.table.core.windows.net`,
  "tasks",
  new DefaultAzureCredential()
);

await client.upsertEntity({
  partitionKey: companyId,
  rowKey: taskId,
  title: "Godkend tilbud",
  status: "open",
});

Blob Storage: filer er private data, indtil andet er besluttet

Et storage account indeholder containere, og hver container indeholder blobs. Brug stabile navne og mapper som logisk struktur, men gem forretningsdata som dokument-ID, ejer og status i en database, hvor de kan valideres og søges.

TypeScript: upload en privat PDF
import { DefaultAzureCredential } from "@azure/identity";
import { BlobServiceClient } from "@azure/storage-blob";

const service = new BlobServiceClient(
  `https://${({}).STORAGE_ACCOUNT}.blob.core.windows.net`,
  new DefaultAzureCredential()
);

const blob = service
  .getContainerClient("documents")
  .getBlockBlobClient(`${companyId}/${documentId}.pdf`);

await blob.uploadData(pdfBuffer, {
  blobHTTPHeaders: { blobContentType: "application/pdf" },
  metadata: { companyId, documentId },
});

Ved upload direkte fra browseren bør backend først kontrollere brugerens adgang og derefter udstede en kortlivet SAS med mindst mulig rettighed til den konkrete handling. En storage account key eller permanent SAS må aldrig ligge i frontendkoden.

Adgang uden connection strings i koden

Brug Microsoft Entra ID, RBAC og managed identity til Azure Functions og andre Azure-services. DefaultAzureCredential kan bruge udviklerens lokale login under udvikling og appens managed identity i Azure. Giv kun den rolle, funktionen behøver – eksempelvis dataadgang til én storage-konto.

  • Slå anonym offentlig blobadgang fra, medmindre indholdet bevidst er offentligt.
  • Undgå Shared Key, og deaktiver den, når integrationsbehovet tillader det.
  • Brug korte SAS-tokens med begrænset scope, rettighed, IP og udløbstid, når delegeret adgang er nødvendig.
  • Overvej private endpoints til følsomme systemer, og luk samtidig den offentlige netværksadgang.

Drift, pris og gendannelse

Redundans beskytter mod infrastrukturfejl, men er ikke det samme som backup. Vælg LRS, ZRS, GRS eller GZRS efter krav til tilgængelighed, geografi og pris. For vigtige blobs bør soft delete og versionering kombineres med en dokumenteret gendannelsestest.

  • Brug lifecycle-regler til at flytte gamle blobs til billigere access tiers eller slette dem efter en aftalt periode.
  • Husk at versionering og soft delete øger lagerforbruget; følg forbruget med budgetter og alarmer.
  • Vælg region og redundans bevidst ud fra datakrav – ikke kun standardvalget i portalen.
  • Test at en slettet eller overskrevet fil faktisk kan gendannes, og hvem der har ansvaret.

Typiske fejl

  • Table Storage vælges som billig SQL: Krav om joins og rapportering opdages først efter datamodellen er i drift.
  • PartitionKey vælges tilfældigt: De vigtigste opslag kræver scanning, eller al trafik rammer samme partition.
  • Filer gemmes i tabellen: Store binære data hører hjemme i Blob Storage; tabellen kan gemme reference og metadata.
  • Containeren gøres offentlig: Et CORS- eller uploadproblem bliver løst ved at åbne mere adgang end nødvendigt.
  • Connection string ligger i repoet: En lækket account key giver bred adgang til storage-kontoen.
  • Redundans kaldes backup: En forkert sletning eller overskrivning replikeres også.

Tjekliste før produktion

  • □ Det er dokumenteret, hvorfor data ligger i Table, Blob, SQL eller et andet lager.
  • □ PartitionKey og RowKey matcher de vigtigste forespørgsler og belastningen.
  • □ Containere er private, og browseren har ingen account key.
  • □ Managed identity og mindst mulige RBAC-roller bruges fra backend.
  • □ Filtype, størrelse, navn og brugeradgang valideres før upload og download.
  • □ Region, redundans, lifecycle, soft delete og versionering er valgt bevidst.
  • □ Budgetalarmer, logs og en testet gendannelsesprocedure findes.

Relaterede guides

Officielle kilder

Azure Storage-funktioner og priser ændres løbende. Kontrollér derfor de aktuelle valg i Microsofts egen dokumentation.