Definição de Dados (DDL)

Autor

Douglas Braga

A DDL (Data Definition Language) permite criar e modificar a estrutura de um banco de dados. Nesta seção, veremos os tipos de dados disponíveis em SQL e os comandos CREATE TABLE, ALTER TABLE e DROP TABLE.

Tipos de Domínio em SQL

Cada coluna de uma tabela deve ter um tipo de dado que determina quais valores ela pode armazenar. Os principais tipos do padrão SQL são:

Tipo Descrição Exemplo
CHAR(n) String de comprimento fixo com exatamente n caracteres CHAR(5) para sigla 'ESETI'
VARCHAR(n) String de comprimento variável com até n caracteres VARCHAR(50) para nomes
INT ou INTEGER Número inteiro (tipicamente 4 bytes) 42, -7
SMALLINT Número inteiro menor (tipicamente 2 bytes) 32767
NUMERIC(p, d) Número decimal com p dígitos no total e d após a vírgula NUMERIC(4,1) para nota 9.5
REAL Número de ponto flutuante de precisão simples 3.14
FLOAT(n) Ponto flutuante com pelo menos n dígitos de precisão FLOAT(10)
DATE Data no formato AAAA-MM-DD '2026-03-10'
TIME Hora no formato HH:MM:SS '08:30:00'
TIMESTAMP Data e hora combinadas '2026-03-10 08:30:00'
BOOLEAN Valor lógico TRUE ou FALSE TRUE

A escolha do tipo de dado adequado é importante por duas razões: integridade (impede que valores inválidos sejam inseridos) e eficiência (tipos menores ocupam menos espaço e são processados mais rapidamente).

CREATE TABLE

O comando CREATE TABLE define uma nova tabela no banco de dados. A sintaxe geral é:

CREATE TABLE nome_da_tabela (
    coluna1  TIPO  [restrições],
    coluna2  TIPO  [restrições],
    ...
    [restrições de tabela]
);

Restrições de integridade

Restrição Descrição
PRIMARY KEY Identifica unicamente cada linha; implica NOT NULL e UNIQUE
NOT NULL Impede que a coluna receba valor nulo
UNIQUE Garante que todos os valores da coluna são distintos
REFERENCES tabela(coluna) Define uma chave estrangeira (integridade referencial)
CHECK (condição) Valida que o valor satisfaz a condição especificada
DEFAULT valor Define um valor padrão quando nenhum é informado

Criando as Tabelas da UnDF

As tabelas devem ser criadas na ordem correta: primeiro as que não têm dependências, depois as que referenciam outras por chave estrangeira.

Tabela centro — sem chaves estrangeiras, criada primeiro:

CREATE TABLE centro (
    id_centro   INTEGER      PRIMARY KEY,
    sigla       VARCHAR(10)  NOT NULL UNIQUE,
    nome_centro VARCHAR(100) NOT NULL
);

Tabela escola — referencia centro:

CREATE TABLE escola (
    id_escola   INTEGER      PRIMARY KEY,
    sigla       VARCHAR(10)  NOT NULL UNIQUE,
    nome_escola VARCHAR(100) NOT NULL,
    id_centro   INTEGER      REFERENCES centro(id_centro)
);

Tabela curso — referencia escola:

CREATE TABLE curso (
    id_curso      INTEGER      PRIMARY KEY,
    sigla_curso   VARCHAR(5)   NOT NULL UNIQUE,
    nome_curso    VARCHAR(100) NOT NULL,
    id_escola     INTEGER      REFERENCES escola(id_escola),
    n_semestres   INTEGER      NOT NULL,
    carga_horaria INTEGER      NOT NULL,
    tipo_curso    VARCHAR(20)  NOT NULL
);

Tabela professor — referencia escola:

CREATE TABLE professor (
    id_prof    INTEGER       PRIMARY KEY,
    nome       VARCHAR(50)   NOT NULL,
    id_escola  INTEGER       REFERENCES escola(id_escola),
    ch_semanal INTEGER       NOT NULL,
    salario    NUMERIC(10,2) NOT NULL
);

Tabela aluno — referencia curso:

CREATE TABLE aluno (
    id_aluno     INTEGER     PRIMARY KEY,
    nome         VARCHAR(50) NOT NULL,
    id_curso     INTEGER     REFERENCES curso(id_curso),
    ano_ingresso INTEGER     NOT NULL
);

Tabela disciplina — referencia curso e exige carga horária positiva:

CREATE TABLE disciplina (
    id_disciplina   INTEGER      PRIMARY KEY,
    nome_disciplina VARCHAR(100) NOT NULL,
    id_curso        INTEGER      REFERENCES curso(id_curso),
    semestre        INTEGER      NOT NULL,
    carga_horaria   INTEGER      NOT NULL CHECK (carga_horaria > 0)
);

Tabela prereq — pré-requisitos entre disciplinas; chave primária composta e duas FKs para disciplina:

CREATE TABLE prereq (
    id_disciplina INTEGER REFERENCES disciplina(id_disciplina),
    id_prereq     INTEGER REFERENCES disciplina(id_disciplina),
    PRIMARY KEY (id_disciplina, id_prereq)
);

Tabela ministra — chave primária composta, referencia disciplina e professor:

CREATE TABLE ministra (
    id_disciplina INTEGER REFERENCES disciplina(id_disciplina),
    ano           INTEGER NOT NULL,
    semestre      INTEGER NOT NULL,
    turma         INTEGER NOT NULL,
    id_prof       INTEGER REFERENCES professor(id_prof),
    horario       VARCHAR(50),
    sala          VARCHAR(20),
    PRIMARY KEY (id_disciplina, ano, semestre, turma)
);

Tabela matricula_disciplina — chave primária composta com chave estrangeira composta:

CREATE TABLE matricula_disciplina (
    id_disciplina INTEGER NOT NULL,
    ano           INTEGER NOT NULL,
    semestre      INTEGER NOT NULL,
    turma         INTEGER NOT NULL,
    id_aluno      INTEGER REFERENCES aluno(id_aluno),
    nota          NUMERIC(4,1),
    aprovado      SMALLINT,
    PRIMARY KEY (id_disciplina, ano, semestre, turma, id_aluno),
    FOREIGN KEY (id_disciplina, ano, semestre, turma)
        REFERENCES ministra(id_disciplina, ano, semestre, turma)
);

Verificando as tabelas criadas

SELECT table_name
FROM   information_schema.tables
WHERE  table_schema = 'public'
ORDER BY table_name;
9 records
table_name
aluno
centro
curso
disciplina
escola
matricula_disciplina
ministra
prereq
professor

O que acontece se a ordem for invertida?

Se tentarmos criar escola antes de centro, o banco de dados retornará um erro:

ERROR: relation "centro" does not exist

Isso ocorre porque REFERENCES centro(id_centro) exige que centro já exista.

ALTER TABLE

O comando ALTER TABLE modifica a estrutura de uma tabela já existente:

-- Adicionar uma nova coluna
ALTER TABLE professor ADD COLUMN email VARCHAR(100);

-- Remover uma coluna
ALTER TABLE professor DROP COLUMN email;

-- Adicionar uma restrição
ALTER TABLE disciplina ADD CONSTRAINT chk_semestre CHECK (semestre BETWEEN 1 AND 10);

DROP TABLE

O comando DROP TABLE remove uma tabela e todos os seus dados permanentemente:

-- Remove a tabela e todos os seus dados
DROP TABLE disciplina;

-- Remove apenas se a tabela existir (evita erro)
DROP TABLE IF EXISTS disciplina;
Aviso

DROP TABLE é uma operação irreversível. Todos os dados da tabela são perdidos permanentemente. Use com cautela em ambientes de produção.

Se outras tabelas referenciam a tabela removida por chave estrangeira, o comando falhará — a menos que CASCADE seja especificado.


Para Praticar

Adicionando e removendo colunas

-- Adicionar email à tabela professor
ALTER TABLE professor ADD COLUMN email VARCHAR(100);

-- Remover a coluna email novamente
ALTER TABLE professor DROP COLUMN email;

Restrição CHECK

O SQL permite validar valores na inserção com CHECK:

-- Adicionar restrição: semestre deve ser entre 1 e 10
ALTER TABLE disciplina
    ADD CONSTRAINT chk_semestre CHECK (semestre BETWEEN 1 AND 10);

O que acontece com NOT NULL em coluna existente?

Se tentarmos adicionar NOT NULL a uma coluna que já possui valores nulos, o banco retorna erro:

-- Isso falharia se horario tiver valores NULL em ministra
ALTER TABLE ministra ALTER COLUMN horario SET NOT NULL;
-- ERROR: column "horario" of relation "ministra" contains null values

A solução é primeiro preencher os valores nulos antes de aplicar a restrição.

Verificando a estrutura de uma tabela

-- Inspecionar colunas, tipos e restrições da tabela professor
SELECT column_name, data_type, is_nullable, column_default
FROM   information_schema.columns
WHERE  table_name = 'professor'
ORDER BY ordinal_position;
5 records
column_name data_type is_nullable column_default
id_prof integer NO NA
nome character varying NO NA
id_escola integer YES NA
ch_semanal integer NO NA
salario numeric NO NA