Databases
February 03, 20247 min read
Relational Databases
Relational database: MySQL
Use Case: Financial transactions, shopping cart, bank, product catalogs, employee records, reporting system
Characteristics:
- ACID properties: Atomicity, Consistency, Isolation, Durability
- Strong consistency
- Transactional - All operations executed or none
- Normalized, no redundancy
- Support complex joins
- Good performance in read-heavy scenarios and simple queries. InnoDB, the default storage engine, provides good support for transactional processing.
Suitable
- High read and write
- Excellent performance in OLAP (Online Analytical Processing) and OLTP (Online Transaction Processing) scenarios.
-- Display data from users table
CREATE TABLE IF NOT EXISTS users (
id INT PRIMARY KEY,
username VARCHAR(50),
email VARCHAR(255)
);
CREATE TABLE IF NOT EXISTS items (
item_id INT PRIMARY KEY,
user_id INT,
item_name VARCHAR(100),
category VARCHAR(50),
price DECIMAL(10, 2),
purchase_date DATE
);
INSERT INTO users (user_id, username, email) VALUES
(1, 'user1', 'user1@example.com'),
(2, 'user2', 'user2@example.com');
INSERT INTO items (item_id, user_id, item_name, category, price, purchase_date) VALUES
(1, 1, 'Laptop', 'Electronics', 1200.00, '2024-02-03'),
(2, 1, 'Headphones', 'Electronics', 99.99, '2024-02-01'),
(3, 2, 'Bookshelf', 'Furniture', 299.99, '2024-01-28');
SELECT * FROM users;
user_id | username | email
--------+----------+---------------------
1 | user1 | user1@example.com
2 | user2 | user2@example.com
SELECT * FROM items;
item_id | user_id | item_name | category | price | purchase_date
--------+---------+-------------+------------+---------+----------------
1 | 1 | Laptop | Electronics| 1200.00| 2024-02-03
2 | 1 | Headphones | Electronics| 99.99 | 2024-02-01
3 | 2 | Bookshelf | Furniture | 299.99 | 2024-01-28
PostgreSQL
Use Case: Employee Records
Characteristics:
- ACID compliance, good for robust transactional support
- Supports a broader range of data types, including advanced types like hstore, JSON, and arrays. It also allows users to define custom data types.
- Provide support for complex queries, advanced indexing, and functions.
Suitable
- High read and write
Almost similar to MySQL as both use SQL.
Non Relational Database
Key-value database: DynamoDb
Use Case: Settings, Session Storage, Caching, Real-time analytics, Leaderboard
Characteristics:
- High throughput with low latency
- Denormalized, duplicated data
- Schema-less - Add new attributes without affecting table schema
Suitable
- High throughput, low latency
aws dynamodb create-table \
--table-name ItemsTable \
--attribute-definitions \
AttributeName=UserID,AttributeType=S \
AttributeName=ItemID,AttributeType=S \
--key-schema \
AttributeName=UserID,KeyType=HASH \
AttributeName=ItemID,KeyType=RANGE \
--provisioned-throughput \
ReadCapacityUnits=5,WriteCapacityUnits=5
aws dynamodb batch-write-item \
--request-items '{
"ItemsTable": [
{
"PutRequest": {
"Item": {
"UserID": {"S": "user1"},
"ItemID": {"S": "item123"},
"ItemName": {"S": "Laptop"},
"Category": {"S": "Electronics"},
"Price": {"N": "1200.00"},
"PurchaseDate": {"S": "2024-02-03"},
"Tag": {"S": "High-end"}
}
}
},
{
"PutRequest": {
"Item": {
"UserID": {"S": "user1"},
"ItemID": {"S": "item456"},
"ItemName": {"S": "Headphones"},
"Category": {"S": "Electronics"},
"Price": {"N": "99.99"},
"PurchaseDate": {"S": "2024-02-01"},
"Tag": {"S": "Wireless"}
}
}
},
{
"PutRequest": {
"Item": {
"UserID": {"S": "user2"},
"ItemID": {"S": "item789"},
"ItemName": {"S": "Bookshelf"},
"Category": {"S": "Furniture"},
"Price": {"N": "299.99"},
"PurchaseDate": {"S": "2024-01-28"},
"Tag": {"S": "Wooden"}
}
}
}
]
}'
[
{
"UserID": "user1",
"ItemID": "item123",
"ItemName": "Laptop",
"Category": "Electronics",
"Price": 1200.00,
"PurchaseDate": "2024-02-03",
"Tag": "High-end"
},
{
"UserID": "user1",
"ItemID": "item456",
"ItemName": "Headphones",
"Category": "Electronics",
"Price": 99.99,
"PurchaseDate": "2024-02-01",
"Tag": "Wireless"
},
{
"UserID": "user2",
"ItemID": "item789",
"ItemName": "Bookshelf",
"Category": "Furniture",
"Price": 299.99,
"PurchaseDate": "2024-01-28",
"Tag": "Wooden"
}
]
Document database: MongoDb
Use Case: Content management, user profiles, catalog, blog
Characteristics:
- Flexible schema
- Scalability and high performance in write-intensive operations.
Suitable
- Write intensive
// MongoDB Collection: UserItems
const itemSchema = new Schema({
itemID: String,
itemName: String,
category: String,
price: Number,
purchaseDate: Date,
tag: String
});
const userSchema = new Schema({
userID: String,
items: [itemSchema]
});
const User = mongoose.model('User', userSchema);
const user1 = new User({
userID: 'user1',
items: [
{
itemID: 'item123',
itemName: 'Laptop',
category: 'Electronics',
price: 1200.00,
purchaseDate: new Date('2024-02-03'),
tag: 'High-end'
},
{
itemID: 'item456',
itemName: 'Headphones',
category: 'Electronics',
price: 99.99,
purchaseDate: new Date('2024-02-01'),
tag: 'Wireless'
}
]
});
user1.save()
.then(() => console.log('Document inserted successfully'))
.catch(err => console.error(err))
.finally(() => mongoose.connection.close());
{
"_id": ObjectId("5f7486514f78a53f508d7a52"),
"userID": "user1",
"items": [
{
"itemID": "item123",
"itemName": "Laptop",
"category": "Electronics",
"price": 1200.00,
"purchaseDate": ISODate("2024-02-03"),
"tag": "High-end"
},
{
"itemID": "item456",
"itemName": "Headphones",
"category": "Electronics",
"price": 99.99,
"purchaseDate": ISODate("2024-02-01"),
"tag": "Wireless"
}
]
}
Graph Database: Neo4j
Use Case: Social network, fraud detection, recommendation engines, network analysis
Characteristics:
- Focus on relationships and patterns
Suitable
- Complex pattern matching
// Create User Nodes
CREATE (:User {userID: 'user1'})
CREATE (:User {userID: 'user2'})
// Create Item Nodes with Relationships to User Nodes
CREATE (:Item {itemID: 'item123', itemName: 'Laptop', category: 'Electronics', price: 1200.00, purchaseDate: '2024-02-03'})-[:OWNED_BY]->(:User {userID: 'user1'})
CREATE (:Item {itemID: 'item456', itemName: 'Headphones', category: 'Electronics', price: 99.99, purchaseDate: '2024-02-01'})-[:OWNED_BY]->(:User {userID: 'user1'})
CREATE (:Item {itemID: 'item789', itemName: 'Bookshelf', category: 'Furniture', price: 299.99, purchaseDate: '2024-01-28'})-[:OWNED_BY]->(:User {userID: 'user2'})
// Create Tag Nodes and Relationships to Item Nodes
CREATE (:Tag {tagName: 'High-end'})
CREATE (:Tag {tagName: 'Wireless'})
CREATE (:Tag {tagName: 'Wooden'})
// Adding Tags to Item Nodes
MATCH (i:Item {itemID: 'item123'})-[:OWNED_BY]->(u:User {userID: 'user1'})
MATCH (t:Tag {tagName: 'High-end'})
CREATE (i)-[:TAGGED_WITH]->(t)
MATCH (i:Item {itemID: 'item456'})-[:OWNED_BY]->(u:User {userID: 'user1'})
MATCH (t:Tag {tagName: 'Wireless'})
CREATE (i)-[:TAGGED_WITH]->(t)
MATCH (i:Item {itemID: 'item789'})-[:OWNED_BY]->(u:User {userID: 'user2'})
MATCH (t:Tag {tagName: 'Wooden'})
CREATE (i)-[:TAGGED_WITH]->(t)
// User Nodes
(:User {userID: 'user1'})
(:User {userID: 'user2'})
// Item Nodes with Relationships to User Nodes
(:Item {itemID: 'item123', itemName: 'Laptop', category: 'Electronics', price: 1200.00, purchaseDate: '2024-02-03'}) -[:OWNED_BY]-> (:User {userID: 'user1'})
(:Item {itemID: 'item456', itemName: 'Headphones', category: 'Electronics', price: 99.99, purchaseDate: '2024-02-01'}) -[:OWNED_BY]-> (:User {userID: 'user1'})
(:Item {itemID: 'item789', itemName: 'Bookshelf', category: 'Furniture', price: 299.99, purchaseDate: '2024-01-28'}) -[:OWNED_BY]-> (:User {userID: 'user2'})
// Tag Nodes and Relationships to Item Nodes
(:Tag {tagName: 'High-end'})
(:Tag {tagName: 'Wireless'})
(:Tag {tagName: 'Wooden'})
// Adding Tags to Item Nodes
(:Item {itemID: 'item123', itemName: 'Laptop', category: 'Electronics', price: 1200.00, purchaseDate: '2024-02-03', tag: 'High-end'}) -[:TAGGED_WITH]-> (:Tag {tagName: 'High-end'})
(:Item {itemID: 'item456', itemName: 'Headphones', category: 'Electronics', price: 99.99, purchaseDate: '2024-02-01', tag: 'Wireless'}) -[:TAGGED_WITH]-> (:Tag {tagName: 'Wireless'})
(:Item {itemID: 'item789', itemName: 'Bookshelf', category: 'Furniture', price: 299.99, purchaseDate: '2024-01-28', tag: 'Wooden'}) -[:TAGGED_WITH]-> (:Tag {tagName: 'Wooden'})
Wide Column database: Cassandra
Use Case: Time-series data, event logging, sensor data storage
Characteristics:
- Write-intensive with horizontal scalability
- No complex joins, query-driven
- Different rows can have different columns
Suitable
- Write intensive
-- Create the users table
CREATE TABLE IF NOT EXISTS users (
user_id UUID PRIMARY KEY,
username TEXT,
email TEXT
);
-- Alter the users table to add the email column
ALTER TABLE users ADD email TEXT;
-- Insert data into the users table
INSERT INTO users (user_id, email, username) VALUES
(73e15d2b-b0a9-45fe-9c67-9071df3a61e0, 'user1@example.com', 'user1'),
(83b8ed8f-aaae-46bc-80db-3bb7df6eb67e, 'user2@example.com', 'user2');
-- Create the items table
CREATE TABLE IF NOT EXISTS items (
user_id UUID,
item_id UUID PRIMARY KEY,
category TEXT,
item_name TEXT,
price DECIMAL,
purchase_date TIMESTAMP,
tags SET<TEXT>
);
-- Insert data into the items table
INSERT INTO items (user_id, item_id, category, item_name, price, purchase_date, tags) VALUES
(73e15d2b-b0a9-45fe-9c67-9071df3a61e0, e0d5b3d4-af42-4f01-823c-54aa53b1a7d9, 'Electronics', 'Laptop', 1200.0, '2024-02-03', {'High-end'}),
(73e15d2b-b0a9-45fe-9c67-9071df3a61e0, 5e62d18a-79e3-4cf0-9a2b-96dd6d54116d, 'Electronics', 'Headphones', 99.99, '2024-02-01', {'Wireless'}),
(83b8ed8f-aaae-46bc-80db-3bb7df6eb67e, a6e717b3-58bc-4e78-8cd5-c79a4d481086, 'Furniture', 'Bookshelf', 299.99, '2024-01-28', {'Wooden'});
-- Create the tags table
CREATE TABLE IF NOT EXISTS tags (
tag_name TEXT PRIMARY KEY
);
-- Insert data into the tags table
INSERT INTO tags (tag_name) VALUES ('High-end'), ('Wireless'), ('Wooden');
-- users table
SELECT * FROM users;
user_id | email | username
--------------------------------------+--------------------+----------
73e15d2b-b0a9-45fe-9c67-9071df3a61e0 | user1@example.com | user1
83b8ed8f-aaae-46bc-80db-3bb7df6eb67e | user2@example.com | user2
-- Select data from the items table
SELECT * FROM items;
user_id | item_id | category | item_name | price | purchase_date | tags
--------------------------------------+--------------------------------------+------------+-----------+--------+---------------------------------+--------------
73e15d2b-b0a9-45fe-9c67-9071df3a61e0 | e0d5b3d4-af42-4f01-823c-54aa53b1a7d9 | Electronics | Laptop | 1200.0 | 2024-02-03 00:00:00.000000000 | {'High-end'}
73e15d2b-b0a9-45fe-9c67-9071df3a61e0 | 5e62d18a-79e3-4cf0-9a2b-96dd6d54116d | Electronics | Headphones | 99.99 | 2024-02-01 00:00:00.000000000 | {'Wireless'}
83b8ed8f-aaae-46bc-80db-3bb7df6eb67e | a6e717b3-58bc-4e78-8cd5-c79a4d481086 | Furniture | Bookshelf | 299.99 | 2024-01-28 00:00:00.000000000 | {'Wooden'}
-- Select data from the tags table
SELECT * FROM tags;
tag_name
----------
High-end
Wireless
Wooden
Time Series: InfluxDB
Use Case: Sensor data, monitoring metrics, log data, financial market data
Characteristics:
- High write for time series data
- Optimized for storing and querying time-stamped data
Suitable
- Storing and querying time-stamped data
CREATE DATABASE measurement
SELECT * FROM measurement WHERE location='room1' AND time >= '2024-06-30T00:00:00Z'
INSERT temperature,location=room1 value=23.5 1625136000000000000