Cosmos DB
Before we start
Survey
Who am I?
Piotr Stapp
- Unique name - just sing a song: "Don't Stapp me know" ;)
- CEO @ Dotnetomaniak
- VP @ devWarsztaty
- Software architect @ Demant Technology Center
- M.Sc (distction) Oxford Brooks University in Web Tech
- M.Sc. Warsaw University of Technology in Computer Science
- And ......
Databases in Azure
Options (built-in)
-
SQL
- Azure SQL
-
Azure Database for PostgreSQL
-
Azure Database for MySQL
-
Azure Database for MariaDB
- NoSQL
- Azure Cosmos DB
- Azure Cache for Redis
- Table storage (simple key value)
- Self-hosted :)
Where is MongoDB or Cassandra?
Azure Cosmos DB
Survey result
What's inside?
Relational DB
Document DB
Relational vs document
Model
- User
- Address
- Orders
{
"id": "9f4657a4-43e3-4a47-9392-6c418035d552",
"key": "7a9f3c4b-3adc-4fb1-a539-47734db30ae0",
"user": {
"Id": 215,
"FirstName": "Wayne",
"LastName": "Hayes",
"FullName": "Wayne Hayes",
"UserName": "Wayne19",
"UserNameLower": "wayne19",
"Email": "Wayne.Hayes@hotmail.com",
"CartId": "a78e749e-ebb2-434c-b658-6795ada0e086",
"Gender": 0,
"Orders": [
{
"OrderId": 217,
"Item": "banana",
"Quantity": 1
}
],
"Address": {
"Type": "company",
"Address": {
"City": "Florineport",
"ZipCode": "38056-0892",
"Street": "Miller Center",
"CountryCode": "QA"
}
}
},
"_rid": "vE5vAKy0d4mWzgMAAAAAAA==",
"_self": "dbs/vE5vAA==/colls/vE5vAKy0d4k=/docs/vE5vAKy0d4mWzgMAAAAAAA==/",
"_etag": "\"0e0000c6-0000-0d00-0000-6005f1f10000\"",
"_attachments": "attachments/",
"_ts": 1611002353
}
Using
Azure CLI
- Creating is easy :)
- 5-15 minutes :(
- I will cheat a bit
az cosmosdb create \
--name $COSMOS_DB_NAME \
--resource-group $group \
--kind MongoDB
Basics
Rules
- No JOIN at all (only client side)
- Bad design == heavy queries == $$$
- Indexes are important 🤪
- Relations:
- Embedded (like Orders)
- Reference (like CartId)
DEMO
Let's look on it 😁
DEMO - Simple search
--simple select
SELECT *
FROM c
WHERE c.user.LastName = 'Bernhard'
--simple count
SELECT count(1)
FROM c
WHERE c.user.LastName = 'Bernhard'
DEMO - Nested search
SELECT c.id, c.user.Id,
c.user.FirstName, c.user.LastName,
o.Item, o.Quantity
FROM c
JOIN o IN c.user.Orders
WHERE 1=1
AND c.user.LastName = 'Bernhard'
AND o.Item='kiwi'
and o.Quantity=1
Request Units (RU)
- Abstraction over:
- CPU
- Memory
- IOPS
- Read 1 KB item costs 1RU
Request Units (RU)
- Bullet One
- Bullet Two
- Bullet Three
DEMO - Calculator
DEMO - Bad one
🙉🙊🙈
SELECT count(1)
FROM c
JOIN o IN c.user.Orders
WHERE 1=1
AND o.Item>'kiwi'
and o.Quantity=1
High Availability
Azure Cosmos DB
Theory
PACELC theorem is an extension to the CAP theorem. It states that in case of network partitioning (P) in a distributed computer system, one has to choose between availability (A) and consistency (C) (as per the CAP theorem), but else (E), even when the system is running normally in the absence of partitions, one has to choose between latency (L) and consistency (C).
Azure Cosmos DB
DEMO SLA DOCUMENTATION
(sorry)
Consistency levels
Consistency levels
- Strong
- Bounded Staleness
- Session
- Consistent Prefix
- Eventual
Strong
- Bullet One
- Bullet Two
- Bullet Three
Bounded Staleness
- Bullet One
- Bullet Two
- Bullet Three
Session
- Bullet One
- Bullet Two
- Bullet Three
Consistent Prefix
- Bullet One
- Bullet Two
- Bullet Three
Eventual
- Bullet One
- Bullet Two
- Bullet Three
Indexes
Types
- kind - range (default) or hash
- precision - default is -1==maximum
- dataType - string or number
Indexes
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*"
}
],
"excludedPaths": [
{
"path": "/user/Address/*"
},
{
"path": "/\"_etag\"/?"
}
],
"compositeIndexes": [
[
{
"path": "/user/LastName",
"order": "ascending"
},
{
"path": "/user/FirstName",
"order": "descending"
}
]
]
}
DEMO - Indexes
SELECT count(1)
FROM c
JOIN o IN c.user.Orders
where 1=1
AND c.user.LastName > 'Z'
AND c.user.FirstName < 'L'
AND CONTAINS(c.user.Email, 'gmail', true)
DEMO - Indexes
-- run on data & db2
SELECT count(1)
FROM c
where c.user.Address.Address.CountryCode="CZ"
Composite indexes
--only on db2
SELECT * FROM c
ORDER BY c.user.LastName desc,
c.user.FirstName asc
Backup
Managed backup
- Default:
- every 4 hours
- only last 2
- Not default -> let's check 😁
How is it working?
- Bullet One
- Bullet Two
- Bullet Three
Restore
- Bullet One
- Bullet Two
- Bullet Three
Pricing tips&tricks
Title Text
- Bullet One
- Bullet Two
- Bullet Three
3 options
- Manual scale
- Autoscale (in theory 1.5x manual)
- Serverless (new option)
- Free tier
Serverless
- 100k RU == 0.0258 EUR
- Availability Zone 1.25x
- Multiregion - not supported yet
Manual / provisioned
- 100 RU == ~4.92 EUR
- Minimum 400 RU per container in container scaling mode
- In database mode formula is more complicated: MAX([containers count]x100RU, 400 RU)
Autoscale
- 100 RU autoscale == 150 RU manual
- Autoscale is always a range: from 10% X to 100% X
- Database model pricing is "better"
- Minimum for 25 containers is still 400 RU, instead of 2500 RU
Free tier
With free tier, you'll get the first 400 RU/s and 5 GB of storage in this account for free. To keep your account free, keep the total RU/s across all resources in the account to 400 RU/s.
ORM - problems
DEMO - Translation
var query = _dbClient.Where<UserDocument>( _collectionUri,
d =>d.User.UserName.ToLower() == criteria.SearchString);
SELECT * FROM c
WHERE LOWER(c.user.UserName) = "{search}"
------------------------------
var query = _dbClient.Where<UserDocument>( _collectionUri,
d => d.User.UserName.Equals(originalSearchString,
StringComparison.OrdinalIgnoreCase));
SELECT * FROM c
WHERE STRINGEQUALS(c.user.UserName, "{search}", true)
----
var query = _dbClient.Where<UserDocument>( _collectionUri,
d => d.User.UserNameLower == originalSearchString);
SELECT * FROM c
WHERE c.user.UserNameLower = "{search}"
More stappuff
Things
- Different languages and types than SQL & documents:
- Mongo, Cassandra, Gremlin, etcd ...
- Geospatial data + search
- Storing & querying dates
- Change feed
- ...
The end?
Not yet :)
Q&A
Twitter: @ptrstpp950
Cosmos DB
By Piotr Stapp
Cosmos DB
- 362