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 valoresNULLna 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:
Figura 2.17 - Diagrama ER - Disciplinas cursadas por um Estudante
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
matriculaindica 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
estudanteedisciplinapossui uma cardinalidade deN:M(NparaM), 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
professoredisciplinapossui cardinalidade1:N(1paraN), isto é, um professor pode lecionar várias disciplinas, mas uma disciplina é lecionada apenas por um úncio professor.Também definiremos que toda
disciplinadeve obrigatoriamente estar relacionada a umprofessor.
A Figura 2.18 apresenta a cardinalidade envolvida nos relacionamentos do diagrama acima:
Figura 2.18 - Exemplo da cardinalidade dos relacionamento do Diagrama ER - Disciplinas cursadas por um Estudante
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):
Figura 2.19 - Modelo lógico - Disciplinas cursadas por um Estudante
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
matriculafoi 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
nomefoi 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_nascimentofoi definida como sendo do tipo data (DATE) e obrigatória (NOT NULL).A coluna
generofoi definida como um caracter de tamanho 1, com uma restrição (check constraint) de uso apenas dos caracteresMouF.A coluna
data_matriculaterá 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
matriculapois uma restrição de chave estrangeira, referenciando a colunamatriculana tabelaestudante.A coluna
codigotambém possui uma restrição de chave estrangeira, referenciando a colunacodigona 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
matriculaecodigocomo a chave primária.