Wednesday, May 22, 2019

Using Unique key constraints in Azure CosmosDB


     Using constraints is a good practice in any database systems. Constraints provide data integrity by validating the data. You can catch invalid data as soon as possible by using Constraints. Most of the NoSQL databases don't support database constraints. CosmosDB offers unique key constraints. You can create a unique key on a field or in a combination of fields.

    Unique key names are case-sensitive, I have good experience on this. If your unique key is in lowercase letters but your data has field with uppercase, CosmosDB will insert null value into unique key first time, you will get an error second time when it tries to insert null again. CosmosDB does not support sparse unique keys. If your unique key is /SSN, you can have only one null value in this field.

    If you like to use unique keys in Azure CosmosDB, you have to create them when you create your containers. You cannot add a unique key to an existing container. Only way to add a unique key to an existing container is, to create a new container and move your data from older container to the new one. Also, you cannot update unique keys just like partition keys. Picking a wrong unique key can be an expensive error.


    CosmosDB will charge you higher Request Units when you insert, update or delete an item in a container that has unique keys. How much more? Well let's test it, I am using SDK3 in the following example. I have a database named OrderTracker. First, I am going to create a container named Orders. This table doesn't have a unique key.


     Next, I am going to insert this Order data into my container by clicking Insert. CosmosDB will return the cost of this request in Request Units. For this request, it returns 11.05 RU


     Now, Let's do the same exact thing with a unique key. In the following example, I define OrderId as a unique key.


      I insert the same Order data into this new container with a unique key. This request costs me 13.26 RU. This is a %20 increase for this request. Unique Keys can help your database, but they are not free in Azure CosmosDB because system needs to do extra work when you Insert and Update data.


    Here is the code to create a container with  or without a unique key by using Azure CosmosDB SDK 3

public async Task<double> CreateContainer(string dbname, string containerId, string partitionid, string uniquekey = null)
        {
            CosmosContainerResponse response;
            if (uniquekey != null && uniquekey.Length <2)
            {
                response = await cosmosClient.Databases[_dbname].Containers.CreateContainerIfNotExistsAsync(containerId, partitionid);
                return response.RequestCharge;
            }
            var partition = new PartitionKeyDefinition();
            partition.Paths.Add(partitionid);
            var uniq = new UniqueKey();
            uniq.Paths.Add(uniquekey);
            var uq = new UniqueKeyPolicy();
            uq.UniqueKeys.Add(uniq);
            response = await cosmosClient.Databases[_dbname].Containers.CreateContainerAsync(new CosmosContainerSettings()
            {
                Id = containerId,
                PartitionKey = partition,
                UniqueKeyPolicy = uq
            });
            return response.RequestCharge;
        }

No comments:

Post a Comment