Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Renatas's avatar

Should I store EVERYTHING in the database?

I'm building a book app, and I need to store book types (like novel, light novel), formats (paperback, hardback, audiobook etc), staff roles (author, illustrator, ...) and languages. Does it make sense to store everything in the DB, even if some tables might never have more than 2-4 rows? Or is something like config files sometimes a better solution?

0 likes
16 replies
Tray2's avatar

YES!

You should store everything in the database

1 like
Renatas's avatar

@Tray2 Thanks :-)

I remember in my previous workplace, the backend team stored some things in app/config, which prompted this question just to make sure I'm on the right path (since they also complained about the need to refactor that haha.)

Tray2's avatar
Tray2
Best Answer
Level 73

@Renatas Somethings might be placed in config files, but I think it's better to use the database.

Just to take an example about a book.

The books have a certain genre, let's say Fantasy. If I place that in a config file, then I still need to give the book that genre. I can of course say FANTASY = 1 and use that 1 as the genre in the books table. However it makes it a bit trickier to display the genre, filter on the genre and such, since you will need to access that config file every time. Putting the genres in a table and eager load it or use a join the get the genre is faster and easier, you never have to look for that value in a file.

Just imagine having to read a file to make an array that you can use in a dropdown to select the genre. If it is a single key value it might belong in a config file, but if it is related to something stored in your database, it probably should be stored there as well.

1 like
Renatas's avatar

@Tray2 changed this as the best answer, thanks for the clear explanation.

Filtering and much more is something I'll want to support for sure, as well as localisation of the interface, so seems like it's the best to store everything in the DB.

1 like
Renatas's avatar

@Tray2 I've been reading your second post, and some questions popped into my head regarding an app I'm building. Like I said in the original post, I want to store authors, as well as other staff. I'm planning to have a staff table and a book_staff table. What I'm unsure of is how to connect staff with their roles. I'm thinking of simply having a pivot role_id in the intermediary table, so that I can easily select which role a staff member fulfilled for a book. Sometimes they can be writers, sometimes illustrators, original creators in case of an adaptation, etc which is why I'm not sure if I want to assign roles that a staff member can do when creating them.. I'd rather let it get selected on a book-per-book basis. Does that make sense? (I guess staff members can sometimes have multiple roles on one book, which I should think how to deal with too...)

Technically, it would be cool to have a $staff->roles, but I think I can just write a scope for that which would get their books and extract unique roles..?

Tray2's avatar

@Renatas The simplest would be to add the book_id to the pivot and call it something like book_role_staff.

  • book_id
  • staff_id
  • role_id
1 like
Renatas's avatar

@Tray2 sounds great. I can still leave it as a many-to-many between books and staff, right?

rawilk's avatar

IMO in most apps I would just use enums for certain things like the format of a book since it's not really going to change much, or at all. Going with the format example, I don't think it's necessary to have to always have to query a db table for formats when you need them, when an enum will work in most use cases. Sure there's caching and stuff, but that's just unnecessary imo.

kokoshneta's avatar

@rawilk For book formats, I use both. I need to support a multi-language interface as well, so for outputting, a single value (as in an enum) isn’t enough:

  • I keep the short and full display names of each format in a table, in each language supported
  • For readability, I refer to the formats in my code through a backed enum with the ID from the database as the value
Renatas's avatar

@kokoshneta I didn't think of it when posting the question, but localisation is something I will want to implement as well. your approach sounds like it may be right for me.

kokoshneta's avatar

@Renatas Just to be clearer than I was last night, when I say “refer to in my code”, I mean that I might have a table like this:

+----+----------------+----------------+----------------+
| id | description_en | description_fr | description_sp |
+----+----------------+----------------+----------------+
|  1 | hardbound      | à la française | cartoné        |
|  2 | paperback      | souple         | rústica        |
+----+----------------+----------------+----------------+

And then in my PHP code, to avoid all the nondescript numbers all over the place (which would need to change if some of the formats change their order in the database for whatever reason) that you get when doing this:

if ($book->format == 2) {
	…
}

– I instead do this:

if ($book->format == BookFormats::paperback) {
	…
}
1 like
rawilk's avatar

@kokoshneta You can still localize enums even if you're using php 8.1 native enums. Just add a method on the enum to determine the label you need for the current lanuage.

enum Format: string
{
    case Paperback = 'paperback';
    case Hardcover = 'hardcover';

    public function label(): string
    {
         return __("enums.format.{$this->value}");
    }
}

Obviously this is a simple example, but there's a lot you can do with native enums now. Laravel makes it simple to cast your columns as enums too.

class Book extends Model
{
    // ...
    protected $casts = [
        'format' => \App\Enums\Format::class,
    ];
}

// Using it:
$book->format->label();

I mean, to each their own, but IMO this is just a cleaner and simpler way to handle static categories like this than storing them in a db table.

kokoshneta's avatar

@rawilk In my case, everything relating to localisation is already stored in the database. If I were making the app from scratch now, I might go for the file-based approach assumed by Laravel’s __ function, but there are already more than 2,000 rows of text/labels used on the site, and an admin system to edit them.

And of course, if you want to be able to filter, group or order books by genre, then you need to store some sort of reference to formats in the database whatever you do. Storing just a string value or an integer in the database and then keeping its corresponding labels and localisation in a file outside the database seems like shaky structuring to me.

Please or to participate in this conversation.