MySQL
Random String Generation
Unique Strings
SQL Tips
Database Management

Generating a random unique 8 character string using MySQL

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

Generating an 8-character string in MySQL is easy. Generating one that is both random-looking and guaranteed unique is the harder part. The key idea is that randomness creates candidates, but uniqueness must still be enforced with a database constraint.

Why RAND() Alone Is Not Enough

If you generate 8-character strings from a limited alphabet, collisions are possible. Even if the chance is low at first, it is never zero. That means a query that only calls RAND() can produce duplicates sooner or later.

So the correct design is:

  • generate a candidate string
  • store it in a column with a UNIQUE constraint
  • retry when a duplicate-key collision occurs

Without the constraint, you do not actually have uniqueness.

A Simple Candidate Generator

One practical MySQL-friendly candidate source is a shortened UUID() value:

sql
SELECT UPPER(SUBSTRING(REPLACE(UUID(), '-', ''), 1, 8)) AS code;

This gives you an 8-character hexadecimal string such as A1F29C4D. It is fast and easy, but truncating to 8 characters means collisions are still theoretically possible. That is why the unique index remains essential.

Enforce Uniqueness in the Table

Start by making the target column unique:

sql
1CREATE TABLE invite_codes (
2    id INT AUTO_INCREMENT PRIMARY KEY,
3    code CHAR(8) NOT NULL UNIQUE
4);

This is the part that actually protects data integrity. Everything else is just candidate generation.

Insert with Retry

One way to handle rare collisions is to try an insert and generate a new candidate if MySQL raises a duplicate-key error. In production systems, that retry loop is often easier to manage in application code, but the same idea can be expressed in SQL logic.

sql
INSERT INTO invite_codes (code)
VALUES (UPPER(SUBSTRING(REPLACE(UUID(), '-', ''), 1, 8)));

If that fails because of a duplicate key, retry with a new candidate. The database stays the source of truth because the UNIQUE constraint decides whether the string is truly unused.

If You Need a Larger Character Set

Hexadecimal characters only give you 16^8 possibilities. If you want more combinations in the same 8-character length, use a base-36 or base-62 alphabet in application code, or construct a more elaborate SQL expression.

For example, a base-36 style candidate can be approximated like this:

sql
SELECT LPAD(UPPER(CONV(FLOOR(RAND() * POW(36, 8)), 10, 36)), 8, '0') AS code;

This increases the address space, but it still does not remove the need for a unique constraint and retry logic.

Random-Looking Versus Security-Safe

If the string is just a short public identifier, a random-looking code may be enough. If it protects access, resets passwords, or acts like a secret token, an 8-character code is often too small and RAND()-style generation is not a strong security design.

That distinction matters:

  • short code for lookup convenience
  • strong token for security

They are not the same requirement.

Application Code Is Often the Best Place

Even though the title asks about MySQL, many teams generate the code in application code and let MySQL enforce uniqueness. That approach usually gives better control over the alphabet, randomness source, retries, and observability.

The database should still keep the UNIQUE constraint. Generating outside the database does not replace that safety net.

Common Pitfalls

  • Assuming a random expression automatically guarantees uniqueness.
  • Truncating UUID() and forgetting that collisions are still possible.
  • Using RAND() for security-sensitive tokens.
  • Generating codes without a unique index on the destination column.
  • Treating collision handling as impossible just because it is rare.

Summary

  • Random generation and guaranteed uniqueness are two different problems.
  • Use MySQL to generate a candidate if you want, but enforce uniqueness with a UNIQUE constraint.
  • Shortened UUID() values are convenient candidate strings.
  • Retry on duplicate-key collisions instead of pretending collisions cannot happen.
  • For security-sensitive use cases, rethink whether an 8-character token is strong enough.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.