Чистый код Короткие заметки веб-разработчика

Как хранить статусы постов/заказов/и т.д. в базе данных MySQL

Наткнулся на интересный вопрос в Тостере: как правильно хранить статусы, например, заказов в интернет магазине. Статусов же много: создан, обрабатывается, оплачен, доставлен и т.д. Пересказываю самую удачную реализацию.

Определимся сразу: у нас фиксированное количество статусов. Так мы сможем сохранить их в конфиге. Но реализация с динамичным количеством статусов не сильно отличается.

Для примера возьмём вот такие статусы заказа:

  1. Новый — new
  2. Оплачен — paid
  3. Получен — recived

Теперь у нас есть два пути: мы можем сохранять ID статута в строке заказа или мы можем строкой указывать чёткий статус — «new».

Проблемы второго подхода весьма очевидны — с каждый запросом к БД мы будем получать на пару байт больше, чем если бы мы просто получили в ответ одну цифру. Более того, статусы у нас расположены в порядке назначения. Например, если мы захотим получить все новые, оплаченные, но не полученные заказы — мы будем вынуждены использовать конструкцию:

SELECT `id`, `name`, `cart`, `status` FROM `orders` WHERE `status` = 'new' OR `status` = 'paid'

Вместо лаконичного

SELECT `id`, `name`, `cart`, `status` FROM `orders` WHERE `status` IN (1,2)

Или

SELECT `id`, `name`, `cart`, `status` FROM `orders` WHERE `status` <= 2

Короче говоря, останавливаемся на цифровых статусов в строках.

Но как сделать, чтобы это было просто и понятно другим программистам? Через 5 лет взглянув на ваш код другой специалист должен понять, что статус 2 означает оплаченный заказ. Этот программист, конечно, может разуть глаза и посмотреть на фронтенде как и что выводится, но мы же здесь пишем чистый код. Поэтому на помощь приходят глобальные константы. Вот реализация на PHP:

define('STATUS_NEW', 1); //Новый
define('STATUS_PAID', 2); //Оплачен
define('STATUS_RECIVED', 3); //Получен

Ну и в коде мы уже можем это элементарно проверить:

if ($order->getStatus() === STATUS_PAID) {
    echo 'Заказ оплачен';
} else{
    echo 'Заказ не оплачен';
}

В Node.js реализация абсолютно точно такая же.

Всё просто и понятно из кода. И через 5 лет другой программист всегда сможет понять что к чему не заходя на фронтенд и поправить что-либо прямо из кода.