I would keep this as NoSQL DB because
a. we don't need strict consistency here i.e. ACID compliance does not seem a mandatory requirement here. I think it is fine if a redirect eventually say in 1 to 2 seconds redirects to the original url. Also, since the system is read heavy I believe the NoSQL DB will be more performative. referencing CAP theorem, which implies that we can only guarantee C (Consistency) or A (Availability) but not both. I am trading off C over A. We definitely need P (Partition Tolerance) for Fault tolerance and Scalability needs.
Schema: JSON
{
id: JSON
short_url: JSON
original_url: JSON
last_accessed: JSON
total_redirects: JSON
country: JSON
city: JSON
is_active: JSON
}
id: Unique Identifier
short_url: Shortened URL
original_url: Actual URL
last_accessed: When was it last used (this may be useful for caching)
total_redirects: How many times this has been used (this may be useful for rate limiting and saving against DDSO Attacks)
country: Location (this is useful for Load balancing, DNS etc.)
city: Location (this is useful for Load balancing, DNS etc.)
is_active: This is to decommission. this is useful for the cleanups
we should index on short_url for after redirects along with id which is used by all apis
Assuming: Authentication and Authorisation is already implemented
Client -> Load Balancer -> Shortening Service -> Load Balancer -> Database
Client -> Give me the Short URL for Original URL
Service -> Does Original URL already exists?
Service -> Create No, if Original URL does not exist, return short url otherwise
Where Client could be User, API, Browser, Curl etc
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?