Chaves
Um dos requisitos fundamentais do modelo relacional é a capacidade de identificar unicamente cada tupla de uma relação. Para isso, utilizamos o conceito de chave.
Definição Formal
Seja \(R\) o schema de uma relação e \(K \subseteq R\) um subconjunto de seus atributos.
Superclave (superkey): \(K\) é uma superclave de \(R\) se os valores de \(K\) são suficientes para identificar unicamente cada tupla em qualquer instância válida da relação.
Chave candidata (candidate key): \(K\) é uma chave candidata de \(R\) se \(K\) é uma superclave minimal, ou seja, nenhum subconjunto próprio de \(K\) é também uma superclave.
Chave primária (primary key): uma chave candidata escolhida pelo projetista do banco de dados para identificar oficialmente as tuplas da relação. É indicada sublinhando-se os atributos no schema.
Exemplos com as Tabelas da UnDF
Relação professor
| id_prof | nome | id_escola | ch_semanal | salario |
|---|---|---|---|---|
| 31200001 | Gustavo Costa | 31 | 20 | 3300 |
| 31400002 | Helena Carvalho | 31 | 40 | 6700 |
| 11400001 | Bruno Teixeira | 11 | 40 | 6500 |
- \(\{id\_prof\}\) é superclave: cada professor tem um identificador único.
- \(\{id\_prof, nome\}\) é superclave: a combinação também identifica unicamente, mas é redundante.
- \(\{nome\}\) não é superclave: poderiam existir dois professores com o mesmo nome.
- \(\{id\_prof\}\) é chave candidata: é a menor superclave (não há subconjunto próprio não vazio que seja superclave).
- \(\{id\_prof\}\) é escolhida como chave primária.
Relação centro
- \(\{id\_centro\}\) é chave candidata e chave primária — cada centro tem um identificador único.
Relação disciplina
- \(\{id\_disciplina\}\) é chave candidata e chave primária.
Relação ministra
A relação ministra registra que um professor ministra uma disciplina em um determinado ano, semestre e turma. Não existe uma coluna única que identifique cada tupla — a chave primária é composta:
\[ministra(\underline{id\_disciplina},\ \underline{ano},\ \underline{semestre},\ \underline{turma},\ id\_prof,\ horario,\ sala)\]
- \(\{id\_disciplina, ano, semestre, turma\}\) é a chave primária composta.
Chave Estrangeira
Uma chave estrangeira (foreign key) é um conjunto de atributos em uma relação cujos valores devem corresponder a valores da chave primária de outra relação. A relação que contém a chave estrangeira é chamada de relação referenciante; a relação que contém a chave primária correspondente é chamada de relação referenciada.
O atributo id_escola em professor é uma chave estrangeira que referencia id_escola em escola:
- Relação referenciante:
professor - Relação referenciada:
escola - Restrição: todo valor de
professor.id_escoladeve existir emescola.id_escola
Isso garante que não seja possível cadastrar um professor em uma escola inexistente. Da mesma forma, curso.id_escola e aluno.id_curso são chaves estrangeiras que referenciam suas respectivas tabelas.
A restrição imposta por uma chave estrangeira é chamada de restrição de integridade referencial (referential integrity constraint) e é uma das formas como o SGBD preserva a consistência dos dados.
Para Praticar
1. Superchaves de disciplina. O schema da relação disciplina é:
\[disciplina(\underline{id\_disciplina},\ nome\_disciplina,\ id\_curso,\ semestre,\ carga\_horaria)\]
Das combinações abaixo, quais são superchaves? Quais são chaves candidatas?
- \(\{id\_disciplina\}\)
- \(\{nome\_disciplina\}\)
- \(\{id\_disciplina,\ semestre\}\)
- \(\{id\_curso,\ semestre,\ nome\_disciplina\}\)
- (a) \(\{id\_disciplina\}\) — superclave e chave candidata: identifica unicamente cada disciplina e é minimal.
- (b) \(\{nome\_disciplina\}\) — não é superclave: dois cursos diferentes podem ter disciplinas com nomes iguais (ex.: “Eletiva I” em PED e uma hipotética em outro curso).
- (c) \(\{id\_disciplina,\ semestre\}\) — superclave mas não candidata: redundante, pois
id_disciplinajá identifica unicamente. - (d) \(\{id\_curso,\ semestre,\ nome\_disciplina\}\) — pode ser superclave se nomes forem únicos por curso/semestre, mas não é minimal.
2. NULL em chave primária. Por que o valor null não é permitido em atributos da chave primária?
A chave primária deve identificar unicamente cada tupla. Se um atributo de PK for null, não é possível determinar se duas tuplas com null representam o mesmo objeto ou objetos diferentes (pois null ≠ null no modelo relacional). Por isso, o SQL impõe implicitamente NOT NULL em todo atributo de chave primária.
3. Chave estrangeira autorreferencial. A tabela prereq tem duas FKs que apontam para a mesma tabela disciplina:
prereq.id_disciplina→disciplina.id_disciplinaprereq.id_prereq→disciplina.id_disciplina
O que aconteceria se tentássemos inserir a tupla (3110201, 3110201) em prereq? Essa inserção violaria alguma restrição?
A tupla (3110201, 3110201) não viola nenhuma restrição de FK (3110201 existe em disciplina) nem de PK (é uma combinação única). No entanto, ela criaria um ciclo de pré-requisito: a disciplina seria pré-requisito de si mesma, o que é semanticamente absurdo. Para evitar isso, seria necessário adicionar uma restrição CHECK (id_disciplina <> id_prereq).