Requirements
- Given a URL, the system should generate a unique shortened URL.
- When the user accesses the shortened URL, the system should redirect them to the original URL.
- The system should be able to handle high traffic and be scalable.
- It should have a low latency, as users expect quick redirection.
- The system should have high availability.
Database Schema
The core table you would need is a table to store the URL mappings:
-- Create UrlTable
CREATE TABLE UrlTable (
id INT PRIMARY KEY AUTO_INCREMENT,
short_url VARCHAR(255),
original_url VARCHAR(255),
created_at TIMESTAMP,
expires_at TIMESTAMP,
user_id INT,
FOREIGN KEY (user_id) REFERENCES UserTable(user_id)
);
-- Create UserTable
CREATE TABLE UserTable (
user_id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(255),
password VARCHAR(255)
);
SQLThis schema is simplified for the demonstration. For a production system, additional data such as URL access statistics and user roles might be necessary.
RESTful API Design
Shorten a URL
POST /api/urls/
Request Body
{
"original_url": "https://www.example.com",
"user_id": 1234,
"expires_at": "2023-06-01T00:00:00Z"
}
JSONResponse
{
"short_url": "https://bit.ly/abc123"
}
JSONAccess a shortened URL
GET /api/urls/{short_url}
Response
Redirect to the original URL or return an error if the URL is expired or doesn’t exist.
Get URL details
GET /api/urls/{short_url}/details
Response
{
"original_url": "https://www.example.com",
"created_at": "2023-05-01T00:00:00Z",
"expires_at": "2023-06-01T00:00:00Z"
}
JSONDelete a shortened URL
DELETE /api/urls/{short_url}
Response
{
"status": "success"
}
JSONHigh-level System Design
URL Shortening
When the user posts a request to shorten a URL, the system will create a new record in the UrlTable
, generate a unique id
, convert this id
to a base62 string, and store it as short_url
.
URL Redirection
When a GET
request is made to access a short_url
, the system will look up the short_url
in the UrlTable
, check if it’s expired, and if not, redirect to the original_url
.
Scalability and High Availability
- To ensure the system can handle high traffic, use load balancers to distribute incoming requests across multiple servers. This design allows for horizontal scaling by adding more servers as needed.
- The database can be sharded based on the
id
to distribute the data and load across multiple database nodes.
Caching
To reduce database load and improve response time, a caching layer can be added. Popular or recently accessed URLs can be cached. Use an expiration policy like LRU (Least Recently Used) to manage the cache.
Cleanup
A separate service can periodically scan the UrlTable
for expired URLs and delete them.
Security
- Ensure that all data is transmitted over secure connections (HTTPS).
- Store only hashed versions of user passwords.
- Implement rate limiting to prevent abuse.
Components
Web Server
Handles incoming HTTP requests and sends HTTP responses. It can be implemented with Node.js, Django, Flask, etc.
Application Server
Handles the logic of URL shortening, URL redirection, etc. This can be implemented in any language like Python, Java, Go, etc.
Database
Stores the URL mappings and other metadata. We can use a key-value store like Redis or a NoSQL database like Cassandra.
Cache
Stores recently or frequently accessed URLs. Can use Memcached or Redis.
Load Balancer
Distributes incoming network traffic across multiple servers to ensure no single server is overwhelmed.
This is a basic outline of a URL shortening system. Many other aspects, such as security, rate limiting, analytics, etc., would need to be considered for a fully-fledged, production-ready system.