Como restringir a inserção na adição de linhas de auto-referência em uma tabela de relação recursiva (uma tabela contém pontos de chave estrangeira em si)?
mysql> SELECT * FROM Employee;
+-----+------+-------------+------+
| SSN | name | designation | MSSN |
+-----+------+-------------+------+
| 1 | A | OWNER | NULL |
| 2 | B | BOSS | 1 |
| 3 | C | WORKER | 2 |
| 4 | D | BOSS | 2 |
| 5 | E | WORKER | 4 |
| 6 | F | WORKER | 1 |
| 7 | G | WORKER | 4 |
| 8 | H | BOSS | 8 |
+-----+------+-------------+------+
8 rows in set (0.00 sec)
Um empregado não pode ser o BOSS
de si mesmos. Por isso
mysql> INSERT INTO Employee VALUES ("8", "H", "BOSS", "8");
Query OK, 1 row affected (0.04 sec)
deve ser recusado por alguma restrição. Como alguém pode adicionar tal restrição?
Se possível sugira sem usar um gatilho.
Isso seria facilmente resolvido com uma restrição de verificação, mas ainda não foi implementada no MySQL (elas são apenas analisadas por "razões de compatibilidade" durante a
CREATE TABLE
definição e completamente ignoradas depois disso).Portanto, a solução 1 é bastante óbvia. Mude para um DBMS que tenha
CHECK
restrições implementadas, como SQL-Server, Oracle, Postgres, etc. (até o MS-Access tem!):A solução 2 é descartar a
designation
coluna completamente. Da sua descrição, todos'Owners'
têm nullmssn
e todos os outros têm seus "gerentes"ssn
armazenados namssn
coluna.Depois de descartar essa coluna, você sempre pode calculá-la em uma exibição:
Isso apenas reforça que, quando um novo funcionário for inserido, se o
mssn
for igual aossn
, o funcionário será atribuído como 'Proprietário'.Porém, você pode ter problemas de desempenho, dependendo de como usa a
designation
coluna. Visualizações dentro de visualizações ou consultas complexas não são o melhor negócio para o otimizador do MySQL.A solução 3 é emular a
CHECK
restrição usando o método descrito nesta resposta: Verificar restrição não funciona?Isso requer que você atualize para o MySQL versão 5.7 ou para o MariaDB 5.5.
A solução 4 é esperar que eles sejam implementados. Há rumores (é 2016 agora) que eles estarão na próxima versão.