Representando localizações geográficas em um aplicativo, o design do modelo de dados subjacente sugere duas opções claras (ou talvez mais?).
Uma tabela com uma coluna parent_id auto-referente uk - london (london parent id = UK id)
ou duas tabelas, com um relacionamento de um para muitos, usando uma chave estrangeira.
Minha preferência é por uma tabela de auto-referência, pois ela facilmente se estende a tantas sub-regiões quanto necessário.
Em geral, as pessoas se desviam das tabelas de auto-referência ou estão OK?
sql
database-design
NimChimpsky
fonte
fonte
hierarchyid
tipo.Necromante.
A resposta correta é: depende de qual mecanismo de banco de dados e de qual ferramenta de gerenciamento.
Vamos dar um exemplo:
temos uma tabela de relatórios,
e um relatório pode ter um pai (ponto de menu, como categoria),
e esse pai pode ter um pai (por exemplo, centro de lucro)
e assim por diante ad infinitum.
O exemplo mais simples de um relacionamento recursivo padrão, como em qualquer entidade / hierarquia auto-referente.
A tabela resultante do SQL-Server é:
Mas você tem um problema:
quando você precisa excluir um ponto de menu com todos os seus submenus, NÃO PODE definir a cascata de exclusão, porque o Microsoft SQL-Server não suporta exclusões em cascata recursivas (por outro lado, o PostGreSQL sim [mas somente se o o gráfico não é cíclico], enquanto o MySQL não gosta desse tipo de estrutura de tabela, porque não suporta CTEs recursivos).
Então você meio que explode integridade / funcionalidade de exclusão, tornando obrigatório implementar essa funcionalidade em seu próprio código ou em um procedimento armazenado (se o seu RDBMS suportar procedimentos armazenados).
Isso sem dúvida explodirá qualquer tipo de importação / exportação de dados dinâmicos totalmente automática, porque você não pode simplesmente executar uma instrução de exclusão para todas as tabelas de acordo com relacionamentos de chave externa (sem referência própria), nem fazer uma seleção simples * e crie uma inserção para cada linha em uma ordem arbitrária.
Por exemplo, quando você cria um script INSERT usando SSMS, o SSMS não obtém a chave estrangeira e, de fato, cria instruções de inserção que inserem entradas com dependências, antes de inserir o pai da dependência, que falhará com um erro , porque a chave estrangeira está no lugar.
No entanto, em sistemas de gerenciamento de banco de dados adequados (como o PostgreSQL), com ferramentas adequadas, isso não deve ser um problema. Apenas entenda que, apenas porque você paga muito pelo seu RDBMS (estou olhando para você, Microsoft; Oracle =?) E / ou seu cinto de ferramentas, isso não significa que está programado corretamente. E o OpenSource (por exemplo, MySQL) também não o torna imune a essas minúcias maravilhosas.
O diabo está nos detalhes, como diz o velho ditado.
Agora, não que você não possa solucionar esses problemas, mas eu realmente não recomendaria se o seu sistema fosse complexo (por exemplo, mais de 200 tabelas).
Além disso, em um ambiente comercial habitual (como retratado por Dilbert), você simplesmente não terá esse tempo.
Uma abordagem muito melhor, embora mais difícil, seria uma tabela de fechamento.
Isso teria o bônus adicional de que ele também funciona no MySQL.
Depois de implementar a funcionalidade de fechamento uma vez, você a trabalhará em locais adicionais em quase nenhum momento.
fonte
É uma boa ideia se o relacionamento é realmente hierárquico, e não um relacionamento de rede (por exemplo, uma Lista de materiais é um relacionamento de rede, não hierárquico).
Pode demorar para consultar. Para acelerar as coisas, você pode usar uma tabela de fechamento.
http://karwin.blogspot.ca/2010/03/rendering-trees-with-closure-tables.html
fonte