дано: есть скрипт на пхп, есть база данных, в ней пишется значение от 1 до 6, ((пакетизация) 1- бан, 2- минимальный пакет и тд (так до 6))
скрипт выводит ответ формата хмл.
в итоге надо в скрипте выгружать это значение из базы и присваивать им значение, т.е что то типа такого:
Если в базе значение равное 1, то скрипт присваивает ему значение BLOCKED и его надо вывести потом также
Если в базе значение равное 2-6, то скрипт присваивает ему значение ACTIVE и его надо вывести потом также
значение от 1 до 6, ((пакетизация) 1- бан, 2- минимальный пакет и тд (так до 6))
Это называется Enum. Если СУБД умеет, то можно и в базе, но как минимум в php. Для, вывода используйте маппер, который пока будет отдавать просто значение Enum, но будет возможность в будущем поменять выводимые названия без переделывания Enum.
Vitsliputsli, Enum очень специфичный формат хранения, с кучей недостатков и подводных камней. Если значений немного, логичнее использовать тиниинт, например, и связанную таблицу соответствий по типу один ко многим.
Enum очень специфичный формат хранения, с кучей недостатков и подводных камней.
выше указанная статья хоть и имеет целых 8 пунктов "Enum - зло", но большинство из них не выдерживает критики.
spoiler
1. С данные обращаются не как с данными
Чушь, техническое хранение данных не должно иметь и не имеет зависимости от его логического представления. Скажем тип boolean слова 'true' и 'false' тоже не хранит прямо в странице.
2. Изменение списка значений ENUM обходится дорого
Очень многие операции DDL в MySQL обходятся дорого. Если ваши таблицы огромны, то действительно стоит подумать использовать ли Enum. Но это не проблема Enum, а все тот же подход, когда мы отказываемся от контроля на стороне БД потому что так дешевле.
3. Невозможно добавить дополнительную информацию
Это не проблема Enum, это мы неправильно выбрали тип данных. Если вы назначили полю тип int, то очень странно удивляться, что туда не залезают буквы.
Тоже самое про "прекращение использования данного варианта", используя int тоже не так то просто "отменить" использование цифры, например 2. Подобная "отмена" это уже слишком сложная логика ее в тип данных не запихнуть.
4. Получение списка уникальных значений ENUM - боль
Это только кажется правильным, но подставлять значения прямо из БД не очень хороший вариант, мы и для boolean можем выводить true/false, но это просто ленивый подход.
5. Тип ENUM имеет весьма незначительный эффект в оптимизации
Все таки Enum в первую очередь это ограничение, поэтому, то что он быстрее это просто дополнительный плюс.
6. Нельзя использовать список ENUM в других таблицах
Сложно назвать это очень существенным недостатком.
7. Тип ENUM имеет много подводных камней
Да, мы привыкли к неявной типизации в MySQL, которая зачастую пораждает серьезные ошибки. Но, здесь с этим все ок, а вариант с Enum '0' '1' и путаницей значений и индексов выглядит надуманным.
8. Портирование ENUM в других СУБД ограничено
Портирование между СУБД всегда боль, т.к. в каждой СУБД множество специфики, поэтому расчитывать на легкое портирование хоть с Enum, хоть без - это странное ожидание.
Реальная проблема здесь только одна, очень ресурсоемкие DDL запросы. Но, тут ничего не поделаешь, MySQL работает только так, и если таблица огромна, то действительно можно хотя бы на Enum съэкономить.
Vitsliputsli, В принципе, проблемы +- те же. Кроме того что, по сути, они легко заменяются ассоциативными массивами, они еще накладывают ряд ограничений, например результаты нельзя сравнивать скалярно.
значения перечисления никогда не являются < или > друг с другом, поскольку эти сравнения не имеют смысла для объектов.
(с) дока.
В продакшн коде крайне редко встречается использование енум, так как смысл его использования ограничить функционал, что почти прямо противоречит задаче сделать код гибким. Задача должна быть ОЧЕНЬ специфичной.
Так же не очень удобно хранить эти данные в коде, так как любое изменение потребует вмешательства в код, в то время как хранение в бд связанной таблицы легко администрируется. Ну и размазывание хранения по нескольким местам не лучшая идея.
Vitsliputsli, Я же написал - формат специфичный. Да, его смысл наложить ограничение, а задачи такого типа являются крайне редкими. Например тогда когда перечисляемые сущности точно имеют ограниченную вариативность, например... даже не знаю, периодическая система элементов?.. Тоже не факт что завтра не откроют новые элементы. Короче сложнее придумать пример где оправдано применение этого типа, чем наоборот.
3. Невозможно добавить дополнительную информацию
Это не проблема Enum, это мы неправильно выбрали тип данных.
Верно, там где не предполагается жесткое ограничение по количеству значений, енум лучше не использовать. Про буквы и цифры сравнение странное, поле int мы можем набить "бесконечным" количеством значений, на свое усмотрение, в отличие от енум, где собственно это ограничение и является "фишкой" формата.
6. Нельзя использовать список ENUM в других таблицах
Сложно назвать это очень существенным недостатком.
Ну, как бы смысл поля заменить связи на внутреннее представление, по этому да, связи по этому полю по сути не нужны. И это как бы противоречит
4. Получение списка уникальных значений ENUM - боль
Это только кажется правильным, но подставлять значения прямо из БД не очень хороший вариант, мы и для boolean можем выводить true/false, но это просто ленивый подход.
так как именно для этого и храним уже готовые варианты, а не для того чтобы еще делать враперы для данных на стороне ЯП.
так как любое изменение потребует вмешательства в код, в то время как хранение в бд связанной таблицы легко администрируется.
это сильно связано с чем больше работаешь, производительность тоже бывает важна и за каждым перечиселнием в БД не находишься, но в любом случае Enum - это не то, что должно часто меняться.
Ну и размазывание хранения по нескольким местам не лучшая идея.
Согласен, вероятно, если есть контроль в приложении, контроль на стороне БД принесет больше проблем (те же DDL), чем плюсов.
В принципе, проблемы +- те же. Кроме того что, по сути, они легко заменяются ассоциативными массивами, они еще накладывают ряд ограничений, например результаты нельзя сравнивать скалярно.
Главный смысл - это ограничение, не так важно будем ли мы использовать enum из php8, или самописный (здесь наверное больше константы подойдут, а не ассоциативный массив).
А сравнивать на больше/меньше это както очень странно, зачем? Зачем сравнивать true и false на больше/меньше? Или сравнивать пол? Как правильно написано в доке, это не имеет смысла, поэтому это ограничение только плюс, оно не позволит делать с Enum то, что делать не нужно.
Про буквы и цифры сравнение странное, поле int мы можем набить "бесконечным" количеством значений, на свое усмотрение, в отличие от енум, где собственно это ограничение и является "фишкой" формата.
Число это такой же Enum, скажем tinyint это перечисление из 255 значений, которые строго определены, ничего кроме них выбрать нельзя. Поэтом когда автор статьи писал "если в дополнение к названию континента требуется сохранить его площадь", то это тоже самое как в tinyint захотеть "напихать" букв.
так как именно для этого и храним уже готовые варианты, а не для того чтобы еще делать враперы для данных на стороне ЯП.
Не совсем, даже если мы храним статус перечислением TO_DO и DONE, то даже на английском пользователю скорее всего выведем алиасы вида "To Do" "Done". Но, согласен, список все равно так или иначе потребуется, а парсить то, в каком виде это лежит в information_schema будет невесело.
А сравнивать на больше/меньше это както очень странно, зачем? Зачем сравнивать true и false на больше/меньше?
Ну, как минимум, сортировка? То есть по полю будет сортировка, но совершенно неочевидным способом, по порядку значений в наборе... Что кстати еще менее очевидно чем сортировка по тру/фалс (которая внутри тиниинт). Это если для мускуля, для пхп это просто еще одно ограничение на уровне кода, которое "просто есть".
Поэтом когда автор статьи писал "если в дополнение к названию континента требуется сохранить его площадь", то это тоже самое как в tinyint захотеть "напихать" букв.
Это к тому что связная таблица удобна в плане расширения, в то время как енум статичен по сути. И да, статья больше предупреждает о том что с енум есть специфика, которую нужно учитывать, так как многие пытаются из енум поиметь замену связям.
Короче, ничуть не умаляя нужности енум как формата, требуется 10 раз подумать прежде чем его использовать, и четко понимать зачем именно енум. В приведенном ТС примере нет четкой уверенности что: 1) список будет статичным, 2) не нужна сортировка по полю, 3) все налагаемые форматом ограничения служат оптимизации работы, а не ошибкой проектирования, 4) нет необходимости хранить более одного значения в связанной таблице (например связанная таблица может иметь слаг, алиас, комментарии и например 2 или 3 перевода).
Короче, ничуть не умаляя нужности енум как формата, требуется 10 раз подумать прежде чем его использовать
Абсолютно согласен.
В общем, насчет enum в СУБД, чтото у меня уверенность пропала, что это хорошая идея, т.к. не факт что даже понимая и принимая ограничения, ограничимся только DDL проблемами. Enum в приложении другое дело, это не очень привычно для php, но не для других языков. Я работал с типизированными enum еще до php8, и на мой взгляд это очень полезная вещь. Но, тут, вы правильно заметили, что нужно понимать что это и зачем вам нужно. И статья это хорошо показывает, что кто-то может ожидать от enum совсем иное, чем они являются.
Очевидным решением выглядит поле типа tinyint и таблица значений со связью 1 ко многим. При запросе используем join по соответствующей связи полей, получая весь набор, включающий имя статуса (ACTIVE, BLOCKED и тд).