2.13. Criando Tabelas
O comando SQL CREATE TABLE
permite criar novas tabelas no banco de dados. A sintaxe básica desse comando é mostrada abaixo:
CREATE TABLE <nome-tabela>
(
<nome-coluna> <tipo-dados> [<restrição-coluna>]
[, <nome-coluna> <tipo-dados> [<restrição-coluna>] ]
[, <restrição-tabela> [, <restrição-tabela> ] ]
);
Onde:
nome-tabela
: O nome de uma tabela deve começar por uma letra (a-z
) ou pelo caracter sublinhado_
, e os demais caracteres podem ser letras, dígitos (0-9
) ou o caracter sublinhado_
. Alguns exemplos de nomes válidos são:foco
,foco_v2
,estudante_disciplina
,populacao_1940
. Opcionalmente, o nome de uma tabela pode ser qualificado com o nome de um esquema. Neste caso usamos a sintaxenome-esquema.nome-tabela
. Como exemplo de nomes de tabelas qualificados com o esquema, podemos citar:public.foco
,geo.lote
,ibge.populacao_brasil
. Discutiremos mais detalhes sobre esquemas na Seção 2.20.Nota
Outro detalhe importante sobre o nome de tabelas consiste no uso de delimitadores com aspas duplas (
"
). Neste caso, podemos criar identificadores contendo caracteres especiais, além de diferenciar letras maiúsculas e minúsculas. Exemplos:"Foco"
,"Foco v2"
,ibge."População do Brasil"
.No entanto, esse recurso deve ser utilizado com moderação para não dificultar o uso dos identificadores na construção de consultas, uma vez que será necessário empregar os delimitadores (
"
).Nota
Os nomes de tabelas são limitados a no máximo 63 bytes. Logo, se usarmos apenas letras (
a-z
), dígitos (0-9
) ou sublinhado (_
), isto significa um identificador de 63 caracteres.nome-coluna
: O nome de colunas segue a mesma regra do nome de tabelas. A única diferença nesse caso é que não usamos a qualificação com o nome do esquema para colunas.tipo-dados
: Podemos usar os tipos de dados discutidos na Seção 2.6.restrição-coluna
: É possível especificar restrições de integridade a serem mantidas pelo SGBD em relação ao valores da coluna. Os tipos mais comuns de restrições incluem:NOT NULL
: Especifica que a coluna é obrigatória.NULL
: Especifica que podemos armazenar valoresNULL
na coluna.CHECK ( expressão )
: Uma expressão lógica envolvendo o valor a ser inserido ou atualizado na coluna que deva ser avaliado como verdadeiro para que o valor seja considerado válido. Usaremos este tipo de restrição nas tabelas que criaremos nessa seção.DEFAULT expressão
: Um valor padrão caso a coluna seja omitida nas inserções.GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY
: Será usado um valor gerado a partir de uma sequência autoincremental.UNIQUE
: Indica que a coluna deverá ter valores únicos.PRIMARY KEY
: Indica que a coluna é chave primária e, portanto, possui valores únicos.REFERENCES
: Permite definir a coluna como uma chave estrangeira, referenciando a coluna de outra tabela.
restrição-tabela
: Após as declarações das colunas, podemos incluir restrições que se aplicam à linha da tabela. Neste caso, podemos ter chaves primárias compostas, chaves estrangeiras compostas, chaves únicas compostas e retrições que envolvam valores de várias colunas. Portanto, podemos declarar as seguintes retrições:CHECK ( expressão )
: Uma expressão lógica que deve ser avaliada como verdadeiro para que os valores sendo inseridos na linha sejam considerados válidos.UNIQUE
: Lista de colunas que formam uma chave única composta.PRIMARY KEY
: Lista de colunas que formam uma chave primária composta.FOREIGN KEY
: Lista de colunas que formam uma chave estrangeira composta.
2.13.1. Estudo de Caso
Considere o diagrama Entidade-Relacionamento (ou ER) mostrado na Figura 2.17 abaixo:
Nesse diagrama temos as seguintes informações:
Um estudante possui propriedades como: número de matrícula, nome, data de nascimento, gênero (masculino ou feminino) e uma data matrícula na escola. O atributo destacado
matricula
indica que ele é único entre os estudantes e, portanto, identifica unicamente um determinado aluno.Uma disciplina possui propriedades como: código, título, número de créditos.
O relacionamento entre
estudante
edisciplina
possui uma cardinalidade deN:M
(N
paraM
), isto é, um estudante pode cursar uma ou mais discplinas e uma disciplina pod ser cursada por um ou mais estudantes. Além disso, esse relacionament possui um atributodata
, que corresponde a data em que o estudante curso a disciplina.Um professor é descrito no sistema apenas pelo código único e seu nome.
O relacionamento entre
professor
edisciplina
possui cardinalidade1:N
(1
paraN
), isto é, um professor pode lecionar várias disciplinas, mas uma disciplina é lecionada apenas por um úncio professor.Também definiremos que toda
disciplina
deve obrigatoriamente estar relacionada a umprofessor
.
A Figura 2.18 apresenta a cardinalidade envolvida nos relacionamentos do diagrama acima:
A partir da compreensão do diagrama ER, podemos criar um novo diagrama mais próximo da implementação que faremos no PostgreSQL (Figura 2.19):
2.13.2. Comandos de Definição de Dados
Agora que temos o modelo das tabelas que queremos criar e sabemos a sintaxe básica do comando CREATE TABLE
, vamos definir as tabelas estudante
, professor
, disciplina
e estudante_disciplina
usando SQL.
Tabela: estudante:
CREATE TABLE estudante
(
matricula INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
nome VARCHAR(30) NOT NULL,
data_nascimento DATE NOT NULL,
genero CHAR(1) NOT NULL CHECK ( genero = 'M' OR genero = 'F' ),
data_matricula DATE NOT NULL DEFAULT CURRENT_DATE
);
Na definição da tabela estudante
temos:
A coluna
matricula
foi definida como chave primária (PRIMARY KEY
), comportando valores do tipo inteiro (INTEGER
) gerados sequencialmente e automaticamente pelo servidor (GENERATED ALWAYS AS IDENTITY
).A coluna
nome
foi definida como uma cadeia de caracteres de tamanho variável limitada a no máximo 30 caracteres, sendo os valores dessa coluna obrigatórios (NOT NULL
).A coluna
data_nascimento
foi definida como sendo do tipo data (DATE
) e obrigatória (NOT NULL
).A coluna
genero
foi definida como um caracter de tamanho 1, com uma restrição (check constraint) de uso apenas dos caracteresM
ouF
.A coluna
data_matricula
terá o valor padrão da data corrente do sistema no caso de ser omitida na inserção.
Tabela: professor
CREATE TABLE professor
(
codigo INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
nome VARCHAR(30) NOT NULL
);
Tabela: disciplina
CREATE TABLE disciplina
(
codigo INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
titulo VARCHAR(30) NOT NULL,
creditos INTEGER NOT NULL CHECK ( creditos >= 1 AND creditos <= 6 ),
professor_codigo INTEGER NOT NULL REFERENCES professor(codigo)
ON DELETE NO ACTION
ON UPDATE CASCADE
);
Nessa tabela temos a definição de uma chave estrangeira, impondo um relacionamento de integridade referencial entre as tabelas professor
e disciplina
nas colunas codigo
e professor_codigo
. A sentença ON DELETE NO ACTION
indica que no caso de remoção de linhas da tabela professor
que tenham disciplinas associadas, deverá ser gerado um erro, impedindo a remoção das linhas da tabela professor
. A setença ON UPDATE CASCADE
, define que no caso de atualização da chave primária na tabela professor
, o novo valor deva ser propagado automaticamente para as linhas relacionadas na tabela disciplina
.
Nota
Abaixo apresentamos como criar a chave estrangeira na seção dedicada a restrições da linha:
CREATE TABLE disciplina2
(
codigo INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
titulo VARCHAR(30) NOT NULL,
creditos INTEGER NOT NULL CHECK ( creditos >= 1 AND creditos <= 6 ),
professor_codigo INTEGER NOT NULL,
FOREIGN KEY (professor_codigo) REFERENCES professor(codigo)
ON DELETE NO ACTION
ON UPDATE CASCADE
);
Tabela: estudante_disciplina
CREATE TABLE estudante_disciplina
(
matricula INTEGER REFERENCES estudante(matricula)
ON DELETE NO ACTION
ON UPDATE CASCADE,
codigo INTEGER REFERENCES disciplina(codigo)
ON DELETE NO ACTION
ON UPDATE CASCADE,
data DATE NOT NULL DEFAULT CURRENT_DATE,
PRIMARY KEY (matricula, codigo)
);
Repare na definição da tabela acima que:
A coluna
matricula
pois uma restrição de chave estrangeira, referenciando a colunamatricula
na tabelaestudante
.A coluna
codigo
também possui uma restrição de chave estrangeira, referenciando a colunacodigo
na tabeladisciplina
.A chave primária dessa tabela é composta e, por isso, foi definida logo após a declaração de todas as colunas. Desta forma, podemos especificar as colunas
matricula
ecodigo
como a chave primária.