Referência Completa de Tipos de Dados SQL

Manual de Todos os Campos do Banco de Dados

Explore cada tipo de campo (VARCHAR, CHAR, INT, DECIMAL, TIMESTAMP, JSON, ENUM...) agrupado por funcionalidade, como configurar no DrawDB e como validar e gravar com PHP 8 + PDO.

6. Datas, Horários & Auditoria 3 tipos

Registro de datas de nascimento, agendamentos, horários de funcionamento e carimbos de auditoria (created_at, updated_at).

DATE (Apenas Data: AAAA-MM-DD)

⭐ Essencial 💾 3 Bytes (MySQL) | 4 Bytes (PostgreSQL)

Armazena somente ano, mês e dia (ex: 1995-08-24), sem horário nem fuso horário.

O tipo DATE ocupa apenas 3 bytes e utiliza o formato universal ISO 8601 (`YYYY-MM-DD`). É ideal para eventos civis que não dependem de hora nem sofrem alteração por fuso horário (uma pessoa nascida em 10/05/1990 continua tendo nascido em 10/05/1990 em qualquer país do mundo).

Limites de Capacidade: De 1000-01-01 até 9999-12-31

✅ Quando Usar (Casos Ideais)

  • • Data de nascimento (`data_nascimento DATE`).
  • • Data de vencimento de boleto/fatura (`data_vencimento DATE`).
  • • Data de admissão, feriados ou início de vigência de contrato.

🚫 Quando NÃO Usar (Armadilhas)

  • • Quando você precisa saber a hora e minuto exatos em que algo ocorreu (use `DATETIME` ou `TIMESTAMP`).
  • • Nunca salve datas como `VARCHAR(10)` no formato `DD/MM/AAAA`! Isso impede o banco de ordenar por data (`ORDER BY`) ou calcular intervalos (`DATEDIFF`). Formate para `d/m/Y` apenas na tela com PHP!

📐 Como Configurar no DrawDB Abrir DrawDB ↗

Type no DrawDB: DATE
Size / Values: Vazio
Default sugerido: Vazio ou CURRENT_DATE
Equivalência nos Dialetos do DrawDB:
MySQL / MariaDB DATE
PostgreSQL DATE
SQLite TEXT (formato YYYY-MM-DD)

📋 Exemplos Reais de Colunas com DATE:

data_nascimento
DATE NULL
Aniversário do usuário
data_vencimento
DATE NOT NULL
Vencimento de uma cobrança
🗄️ SQL DDL (Importar no DrawDB: Import > SQL)
CREATE TABLE faturas (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    cliente_id BIGINT UNSIGNED NOT NULL,
    valor DECIMAL(10, 2) NOT NULL,
    data_emissao DATE NOT NULL,
    data_vencimento DATE NOT NULL
);
🐘 Como Validar e Salvar no PHP 8 + PDO
<?php
declare(strict_types=1);

// 1. Convertendo data brasileira (DD/MM/YYYY) para padrão do banco (YYYY-MM-DD) com DateTimeImmutable
$inputUsuario = '25/12/2026';
$dataVencimento = DateTimeImmutable::createFromFormat('!d/m/Y', $inputUsuario);
$erros = DateTimeImmutable::getLastErrors();

if (!$dataVencimento || ($erros !== false && ($erros['warning_count'] > 0 || $erros['error_count'] > 0))) {
    throw new InvalidArgumentException('Data inválida.');
}

// 2. Salvando no banco no formato ISO Y-m-d
$stmt = $pdo->prepare('
    INSERT INTO faturas (cliente_id, valor, data_emissao, data_vencimento)
    VALUES (:cliente, :valor, :emissao, :vencimento)
');
$stmt->bindValue(':cliente', 10, PDO::PARAM_INT);
$stmt->bindValue(':valor', '250.00', PDO::PARAM_STR);
$stmt->bindValue(':emissao', (new DateTimeImmutable('today'))->format('Y-m-d'), PDO::PARAM_STR);
$stmt->bindValue(':vencimento', $dataVencimento->format('Y-m-d'), PDO::PARAM_STR);
$stmt->execute();

// 3. Ao exibir na tela em PHP:
echo 'Vencimento: ' . $dataVencimento->format('d/m/Y'); // 25/12/2026

DATETIME vs TIMESTAMP (Data + Hora)

⭐ Essencial 💾 TIMESTAMP: 4 Bytes (MySQL) | DATETIME: 5 a 8 Bytes

Registros de data e hora completa (AAAA-MM-DD HH:MM:SS) para eventos, agendamentos e auditoria.

Ambos guardam data e hora (`YYYY-MM-DD HH:MM:SS`), mas têm uma diferença vital: o `TIMESTAMP` converte automaticamente o horário da sessão para UTC ao salvar no disco e converte de volta para o fuso horário atual ao consultar (ótimo para `created_at` e `updated_at`), ocupando 4 bytes (nota: no MySQL de 32-bits/antigo o TIMESTAMP vai até 2038; no PostgreSQL `TIMESTAMPTZ` ocupa 8 bytes e não tem limite de 2038). Já o `DATETIME` ocupa 5 a 8 bytes, vai do ano 1000 ao 9999 e guarda a data/hora literal sem conversão de fuso (ideal para agendamentos futuros como consultas médicas).

Limites de Capacidade: DATETIME: 1000-01-01 00:00:00 a 9999-12-31 23:59:59 | TIMESTAMP MySQL: 1970 a 2038

✅ Quando Usar (Casos Ideais)

  • • Use `TIMESTAMP` (ou `TIMESTAMPTZ` no Postgres) para carimbos de auditoria do momento exato em que algo aconteceu: `criado_em`, `atualizado_em`, `pago_em`, `deletado_em`.
  • • Use `DATETIME` para datas futuras distantes (após 2038 no MySQL) ou agendamentos civis fixos (`data_hora_consulta DATETIME`).

🚫 Quando NÃO Usar (Armadilhas)

  • • Não use `INT` para guardar Unix Timestamp manual se quiser usar funções de data nativas do SQL de forma legível nos relatórios e no DrawDB.

📐 Como Configurar no DrawDB Abrir DrawDB ↗

Type no DrawDB: TIMESTAMP ou DATETIME
Size / Values: Vazio
Default sugerido: CURRENT_TIMESTAMP
Equivalência nos Dialetos do DrawDB:
MySQL / MariaDB DATETIME ou TIMESTAMP DEFAULT CURRENT_TIMESTAMP
PostgreSQL TIMESTAMPTZ (TIMESTAMP WITH TIME ZONE) DEFAULT CURRENT_TIMESTAMP
SQLite DATETIME DEFAULT CURRENT_TIMESTAMP

📋 Exemplos Reais de Colunas com TIMESTAMP:

criado_em
TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
Auditoria automática de criação
agendado_para
DATETIME NOT NULL
Data e hora de uma consulta médica
deletado_em
TIMESTAMP NULL DEFAULT NULL
Soft Delete (exclusão lógica)
🗄️ SQL DDL (Importar no DrawDB: Import > SQL)
CREATE TABLE consultas_medicas (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    paciente_id BIGINT UNSIGNED NOT NULL,
    agendado_para DATETIME NOT NULL,
    criado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
    atualizado_em TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    cancelado_em TIMESTAMP NULL DEFAULT NULL
);
🐘 Como Validar e Salvar no PHP 8 + PDO
<?php
declare(strict_types=1);

date_default_timezone_set('America/Sao_Paulo');

$agendamento = new DateTimeImmutable('2026-11-10 14:30:00');

$stmt = $pdo->prepare('
    INSERT INTO consultas_medicas (paciente_id, agendado_para)
    VALUES (:paciente_id, :agendado_para)
');
$stmt->bindValue(':paciente_id', 77, PDO::PARAM_INT);
$stmt->bindValue(':agendado_para', $agendamento->format('Y-m-d H:i:s'), PDO::PARAM_STR);
$stmt->execute();

TIME & YEAR (Hora Isolada e Ano)

💾 TIME: 3 Bytes | YEAR: 1 Byte

TIME armazena horários do dia ou durações (HH:MM:SS); YEAR armazena um ano em 1 Byte.

O tipo `TIME` (3 bytes) é ideal para horários recorrentes que independem de um dia específico, como horário de abertura e fechamento de uma loja (`08:00:00` às `18:00:00`). Já o tipo `YEAR` no MySQL ocupa apenas 1 byte para anos entre 1901 e 2155.

Limites de Capacidade: TIME: -838:59:59 a 838:59:59 | YEAR: 1901 a 2155

✅ Quando Usar (Casos Ideais)

  • • Horário comercial de abertura e fechamento (`abre_as TIME`, `fecha_as TIME`).
  • • Horário de início de uma turma escolar (`horario_aula TIME`).

🚫 Quando NÃO Usar (Armadilhas)

  • • Para anos fora da faixa de 1901 a 2155 (use `SMALLINT` em vez de `YEAR` para maior compatibilidade com PostgreSQL e SQLite).

📐 Como Configurar no DrawDB Abrir DrawDB ↗

Type no DrawDB: TIME
Size / Values: Vazio
Default sugerido: Ex: 08:00:00
Equivalência nos Dialetos do DrawDB:
MySQL / MariaDB TIME
PostgreSQL TIME
SQLite TEXT

📋 Exemplos Reais de Colunas com TIME:

horario_abertura
TIME NOT NULL
Hora em que a loja abre (ex: 08:30:00)
horario_fechamento
TIME NOT NULL
Hora em que a loja fecha (ex: 18:00:00)
🗄️ SQL DDL (Importar no DrawDB: Import > SQL)
CREATE TABLE horarios_funcionamento (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    dia_semana TINYINT UNSIGNED NOT NULL COMMENT '1=Dom, 2=Seg ... 7=Sab',
    horario_abertura TIME NOT NULL,
    horario_fechamento TIME NOT NULL
);
🐘 Como Validar e Salvar no PHP 8 + PDO
<?php
declare(strict_types=1);

$abertura   = '08:30:00';
$fechamento = '18:00:00';

if (!preg_match('/^(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $abertura)) {
    throw new InvalidArgumentException('Horário inválido.');
}

$stmt = $pdo->prepare('
    INSERT INTO horarios_funcionamento (dia_semana, horario_abertura, horario_fechamento)
    VALUES (:dia, :abre, :fecha)
');
$stmt->bindValue(':dia', 2, PDO::PARAM_INT); // Segunda-feira
$stmt->bindValue(':abre', $abertura, PDO::PARAM_STR);
$stmt->bindValue(':fecha', $fechamento, PDO::PARAM_STR);
$stmt->execute();