← Voltar para 8. Opções & Conjuntos (Listas)
8. Opções & Conjuntos (Listas)

ENUM (Lista Fechada de Opções)

Permite que a coluna assuma apenas UM valor dentre uma lista pré-definida de opções.

💾 Espaço em Disco: 1 Byte (até 255 opções) ou 2 Bytes (até 65.535 opções) 📏 Limites: 1 valor escolhido por registro dentre a lista declarada

Internamente no MySQL, o ENUM armazena o texto das opções no metadado da tabela e grava apenas um índice numérico compacto de 1 byte na linha (para até 255 opções), mas exibe e filtra como string. No PHP 8.1+, combina perfeitamente com `BackedEnum`. Alternativamente, em sistemas onde a lista de opções muda com frequência, muitos arquitetos preferem `VARCHAR(30)` validado por um `enum` do PHP ou uma tabela de domínio auxiliar.

✅ Quando Usar

  • •Status de máquina de estados estável: `ENUM('pendente', 'pago', 'enviado', 'cancelado')`.
  • •Tipo de pessoa: `ENUM('PF', 'PJ')`.
  • •Nível de severidade de um log: `ENUM('info', 'warning', 'error', 'critical')`.

🚫 Quando NÃO Usar

  • •Listas que o administrador do sistema pode cadastrar ou editar pelo painel (ex: categorias de produtos, cargos da empresa) — para isso, crie uma tabela separada com Foreign Key!

📐 Configuração no DrawDB

Type:
ENUM
Size / Values:
'pendente', 'pago', 'enviado', 'cancelado'
Default:
'pendente'
MySQL / MariaDB
ENUM('pendente', 'pago', 'cancelado') NOT NULL DEFAULT 'pendente'
PostgreSQL
CREATE TYPE status_pedido AS ENUM (...) ou VARCHAR(20) CHECK (...)
SQLite
TEXT CHECK(status IN ('pendente', 'pago', 'cancelado'))
🗄️ SQL DDL (Pronto para Importar no DrawDB)
CREATE TABLE pagamentos (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    pedido_id BIGINT UNSIGNED NOT NULL,
    metodo ENUM('pix', 'cartao_credito', 'boleto') NOT NULL,
    status ENUM('aguardando', 'aprovado', 'recusado', 'estornado') NOT NULL DEFAULT 'aguardando'
);
🐘 Exemplo Prático em PHP 8 + PDO
<?php
declare(strict_types=1);

// Usando Backed Enum nativo do PHP 8.1+ sincronizado com o banco!
enum StatusPagamento: string {
    case Aguardando = 'aguardando';
    case Aprovado   = 'aprovado';
    case Recusado   = 'recusado';
    case Estornado  = 'estornado';
}

// Validando uma string recebida via requisição com tryFrom()
$statusRecebido = StatusPagamento::tryFrom($_POST['status'] ?? 'aguardando');
if ($statusRecebido === null) {
    throw new ValueError('Status de pagamento inválido.');
}

$stmt = $pdo->prepare('
    INSERT INTO pagamentos (pedido_id, metodo, status)
    VALUES (:pedido_id, :metodo, :status)
');
$stmt->bindValue(':pedido_id', 1020, PDO::PARAM_INT);
$stmt->bindValue(':metodo', 'pix', PDO::PARAM_STR);
$stmt->bindValue(':status', $statusRecebido->value, PDO::PARAM_STR);
$stmt->execute();