rlim

Identifiers in Databases: IDs, UUIDs, or Slugs

written by Ricky Lim on 2025-05-14

Choosing the right identifier for database records is essential not just for security and scalability, but also for optimizing data management and user experience. For data scientists, this choice can significantly impact query efficiency, data integrity and overall system performance.

In this blog, we're going to explore three common strategies for database identifiers and when to use each one with examples from Django.

Auto-incremented IDs

These are sequential integers generated by the database such as in PostgresSQL.

Pros

Cons

Example

By default, in every model, Django adds an auto-incremented integer id as the primary key, unless you specify otherwise.

class BlogPost(models.Model):
    title = models.CharField(max_length=200)

If you check the database table for this model, it will have columns: id (auto-incremented primary key) and title - even though id isn't explicitly defined.

UUIDs

Universally Unique Identifiers, are generated random strings e.g post/3a10a04e-5092-428f-a7eb-ef7df53057ec.

Pros

Cons:

Example

In this example, id is explicitly specified as a uuid.

class BlogPost(models.Model):
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
    )
    title = models.CharField(max_length=200)

Slugs

A URL-friendly labels. For example: post/identifiers-in-databases-ids-uuids-or-slugs

Pros

Cons

Example

In this example, we add title_slug field to our model.

class BlogPost(models.Model):
    title = models.CharField(max_length=200)
    # Set unique to true, to tell Django to index this column for fast lookups
    title_slug = models.SlugField(unique=True)

In your django-admin, you can set up the prepopulated_fileds so that the title_slug is auto-filled from another field such as title as you type.

# admin.py
class BlogPostAdmin(admin.ModelAdmin):
    prepopulated_fields = {"title_slug": ("title",)}

Use title_slug in your views and URLs to create user-friendly URLs for each blog post:

# views.py
class SinglePostView(View):
    template_name = "blog/post-detail.html"
    model = BlogPost

    def get(self, request, title_slug):
        post = BlogPost.objects.get(title_slug=title_slug)

        context = {
            "post": post,
        }

        return render(request, "blog/post-detail.html", context)

# urls.py
urlpatterns = [
    path("post/<slug:title_slug>", views.SinglePostView.as_view(), name="post-detail-page"),
]

Key Takeaways

Here's a quick comparison of three common identifiers in databases - based on their typical use cases and trade-offs:

Criteria Auto-ID UUID Slug
Use Case Internal APIs Distributed apps Public URLs
Security Low High Medium
Uniqueness Single-database Across-databases Per-record
Scalability Poor Excellent Good