Windows Azure Table PartitionKey Options for TableDomainServices

There are three primary strategies when it comes to partitioning entities across Windows Azure Table Storage. You can:

  • Put everything in the same partition
  • Put everything in different partitions
  • Put things in two or more specific partitions

A full discussion of these options can be found in the Table Storage whitepaper, but I’ll take some time in the post to show how each strategy can be implemented in your TableDomainService. Each option hinges around the PartitionKey value in your TableDomainService and each of your entities.

The Single-PartitionKey Strategy

Using a single partition offers some attractive features like optimized querying and transactional updating. Since these fall most in line with existing domain service patterns, we chose to make this the default option in the TableDomainService.

By default, TableDomainService.PartitionKey returns the name of your domain service. This key is passed through to the EntityContext which makes sure to put all your entities in the same partition. It also knows enough to only search for your entities in that partition by optimizing it’s query.

In all three options, an entity’s PartitionKey will not be set if you specify it before adding the entity to the EntityContext. For this reason, it’s usually not a good idea to set the entity’s partition key explicitly when using this strategy.

The Unique-PartitionKey Strategy

Windows Azure will place entities with unique PartitionKeys in separate partitions. Using this strategy will give you the maximum amount of scalability.

To operate in this strategy, override TableDomainService.PartitionKey and return null. This tells both your domain service and the EntityContext they can’t assume a single key.

The Specific-PartitionKey Strategy

The final option allows you to balance the behaviors of the first two options in the way that best suits your application. You can improve scalability over using a single key while preserving transactional semantics over entities in the same partition.

For this strategy, you’ll again need to override TableDomainService.PartitionKey and return null. This time, however, you’ll also need to set every entity’s PartitionKey explicitly. At this point, partitioning is fully under your control.

Which do I choose?

There’s no right or wrong strategy to use. The single-key strategy is the default because it should feel most familiar to developers. However, it doesn’t leverage the massive scaling potential of the cloud. It’s definitely a topic that deserves some up-front consideration before starting development. If nothing else, read through Section 3 of the whitepaper to familiarize yourself enough with partitioning to make an educated decision.

Comments (1)

  1. I'm adding this comment in case any others have the same issue I did.  I'm migrating an app using the specific partition-key strategy to ria services with tabledomainservices.  No matter what I tried I could not get a simple drag-drop datagrid to populate with data.  After debugging and watching the tablecontext, I found the default query was filtered by partitionKey == <tabledomainservice class name here>.  Of course that partitionKey matched nothing in my existing tables so no results returned.  The solution as provided above is to "override TableDomainService.PartitionKey and return null. This time, however, you’ll also need to set every entity’s PartitionKey explicitly".    Thanks Kyle!