Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here
Premium Members Only
Join to unlock this tutorial and all of our courses.
Tutorial Premium Tutorial

Laravel: Why (Not) Use JSON DB Columns? Practical Examples.

July 12, 2023
8 min read

JSON columns in the database seem like a solution if you're not sure about the structure of data. But quite often, they lead to more problems in the future. In this article, I want to show both good and bad cases of using JSON columns with Laravel examples.

If I had to summarize it all in one sentence, it would be this.

Don't use JSON columns if you need to search within that data later.

To rephrase this, it's ok (-ish) to use JSON columns if you just get a single DB record and then process data within that record.

In other words, this isn't good in most cases:

// Migration:
$table->json('options');
 
// Controller:
$users = DB::table('users')
->whereJsonContains('options->languages', 'en')
->get();

And this is good:

$user = User::find($id);
// Do JSON manipulation in Laravel from $user->options data

But it's not so black and white. There are various examples. So, let's get practical.


Legit Cases to Use JSON Columns

These are real-life examples of JSON columns that I've found.

Legit Example 1. Translations.

Packages like spatie/laravel-translatable store data in JSON and then get the translations for a single record with this Laravel code:

$newsItem->getTranslations('name');
// returns ['en' => 'Name in English', 'nl' => 'Naam in het Nederlands']

I would argue with myself this is a semi-legit example because...

Premium Members Only

This advanced tutorial is available exclusively to Laravel Daily Premium members.

Premium membership includes:

Access to all premium tutorials
Video and Text Courses
Private Discord Channel

Comments & Discussion

SH
Silvan Hagen ✓ Link copied!

Great article, thanks a lot! For a project I'm working on, I built a flexible scraper. As we don't know what kind of data is coming in, for example how many open graph tags, if there are any or the number of images with suitable size on the page are found, I store these values in JSON columns. Luckily I don't have to search in these columns, it's simply for storing the data. Later on the data gets transformed into another model to be used. So for example the open graph image becomes a Media item, attached to the item unless there is none in which case, a suitable image from all images collected from the page is selected. Just wanted to share my use case and that I absolutely agree to be careful when to use JSON columns.

J
jakub ✓ Link copied!

1NF - a single field must not hold more than one value (atomicity)

Someone who added json type to databases should burn in hell.

SH
Silvan Hagen ✓ Link copied!

So how would you store an unknown number of values? Adding more fields on the fly?

J
jakub ✓ Link copied!

This is what I usually do.

In every JSON that are several fields that I may need to use for searching, so I can create a table having those fields and file_prefix (or file_path) column.

The table also contains standard fields like id, user_id etc...

Fields that hold values extracted from JSON in 99% of cases can be indexed and nullable. This allows for efficient searching.

I store JSON content in files uploaded to external storage like s3. Since I always run everything in the same cloud infrastructure and same region, there is almost no latency when grabbing files from storage. ......................................................................................................................................................

In theory I instead of storing json in file I could have just a text filed called json_content which would store a single value - a json content. But some of those jsons may be quite big, thus I store them in files.

SH
Silvan Hagen ✓ Link copied!

Interesting approach, thanks for sharing. I thought about storing the json data in files too, but since I don't need to search them before turning the data into multiple models with single values for columns, I decided to use json fields in the database.

J
jakub ✓ Link copied!

You are welcome.

I
iotron ✓ Link copied!

https://youtu.be/jkKVy5UQ6Y0

Hi, in this video, the json column is performing similar to single columns for about 1000 rows. I have an online store which uses the db structure as above with $product->attributes->size->M with attributes being the json column. I have created a virtual column pointing to attributes->size on which the query runs. Is this approach good for performance?

PK
Povilas Korop ✓ Link copied!

On small size databases (1000 rows is actually small), with small number of visitors, you would indeed probably not feel much difference in performance.

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.