Représentant des emplacements géographiques au sein d’une application, la conception du modèle de données sous-jacent suggère deux options claires (ou peut-être plus?).
Une table avec une colonne auto-référence parent_id uk - london (id parent london = id UK)
ou deux tables, avec une relation un à plusieurs en utilisant une clé étrangère.
Ma préférence va à une table d'auto-évaluation car elle permet de s'étendre facilement dans autant de sous-régions que nécessaire.
En général, les gens s'éloignent-ils des tables d'auto-référencement ou sont-ils OK?
sql
database-design
NimChimpsky
la source
la source
hierarchyid
type.Nécromancie.
La réponse correcte est: cela dépend de quel moteur de base de données et de quel outil de gestion.
Prenons un exemple:
nous avons une table de rapport,
et un rapport peut avoir un parent (menupoint, comme une catégorie),
et ce parent peut lui-même avoir un parent (par exemple, Centre de profit),
et ainsi de suite à l'infini.
L'exemple le plus simple d'une relation récursive standard, comme avec toute entité / hiérarchie à référence automatique.
La table SQL-Server résultante est:
Mais vous rencontrez un problème:
lorsque vous devez supprimer un point de menu avec tous ses sous-points, vous NE POUVEZ PAS définir delete-cascade, car Microsoft SQL-Server ne prend pas en charge les suppressions en cascade récursives (par contre, PostGreSQL ne [ graph n'est pas cyclique], alors que MySQL n'aime pas du tout ce type de structure de tableau, car il ne supporte pas les CTE récursifs).
Vous détruisez donc un peu l’intégrité / fonctionnalité de suppression, ce qui rend obligatoire l’implémentation de cette fonctionnalité dans votre propre code ou dans une procédure stockée (si votre SGBDR prend en charge les procédures stockées).
Cela entraînera sans aucun doute toute sorte d'importation / exportation de données dynamiques entièrement automatique, car vous ne pouvez pas simplement exécuter une instruction delete pour toutes les tables en fonction de relations de clé étrangère (sans auto-référencement), ni effectuer une simple sélection. * et créez un insert pour chaque ligne dans un ordre arbitraire.
Par exemple, lorsque vous créez un script INSERT à l'aide de SSMS, SSMS ne récupère pas la clé étrangère et crée donc bien des instructions d'insertion qui insèrent des entrées avec des dépendances, avant d'insérer le parent de la dépendance, ce qui échouera avec une erreur. , car la clé étrangère est en place.
Cependant, sur des systèmes de gestion de base de données appropriés (tels que PostgreSQL), avec un outillage approprié, cela ne devrait pas poser de problème. Comprenez simplement que le fait que vous payiez beaucoup pour votre SGBDR (je vous regarde, Microsoft; Oracle =?) Et / ou sa ceinture d’outils ne signifie pas qu’il est programmé correctement. Et OpenSource (par exemple, MySQL) ne vous rend pas non plus immunisé contre de telles minuties.
Le diable est dans les détails, comme le dit le vieil adage.
Maintenant, non pas que vous ne puissiez pas contourner de tels problèmes, mais je ne le recommanderais vraiment pas, si votre système devait être complexe (par exemple, plus de 200 tables).
De plus, dans un contexte commercial habituel (tel que décrit par Dilbert), on ne vous donnera tout simplement pas ce temps.
Une approche bien meilleure, bien que plus difficile, consisterait en une table de fermeture.
Cela aurait l'avantage supplémentaire que cela fonctionne également sur MySQL.
Une fois que vous avez implémenté la fonctionnalité de fermeture une fois, vous la travaillerez à des emplacements supplémentaires en un rien de temps.
la source
C'est une bonne idée si la relation est réellement hiérarchique et non pas une relation de réseau (par exemple, une nomenclature est une relation de réseau, pas une relation hiérarchique).
Il peut être lent à interroger. Pour accélérer les choses, vous pouvez utiliser une table de fermeture.
http://karwin.blogspot.ca/2010/03/rendering-trees-with-closure-tables.html
la source