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();