Lorsque vous demandez un nouveau HierarchyID entre deux autres, le résultat devient progressivement plus long. Par exemple, entre 2/5.6 et 2/5.7 il n'y a que 2/5.6.1 et autres 4 chemins de composants. Le type de données HierarchyID est limité à 800 octets, vous ne pouvez donc pas le répéter indéfiniment. Là encore, les types entiers sont également limités, mais ce n'est pas un problème en pratique. Devrais-je périodiquement défragmenter ma table pour que la taille ne devienne pas illimitée?Dois-je m'inquiéter de manquer de HiérarchieID?
Répondre
Il est considéré comme une «meilleure pratique» avec le hierarchyid
d '«ajouter» de nouveaux ID de sorte que vous n'utilisiez pas ces états intermédiaires (tels que /2/5.6/
). Si votre hierarchyid
est une clé primaire en cluster, les performances sont alors mauvaises, ce qui entraînera des divisions de pages similaires à celles d'un uniqueidentifier
.
Si vous générez enfants séquentiels, il est hautement improbable que vous ayez à vous soucier de l'épuisement; vous pouvez avoir littéralement des millions d'enfants pour chaque parent.
Here est un exemple de la façon dont vous êtes censé générer des valeurs hierarchyid
:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
UPDATE Hierarchy
SET @LastChild = LastChild = HId.GetDescendant(LastChild, NULL)
WHERE HId = @ParentID
INSERT Hierarchy (HId, ...)
VALUES (@LastChild, ...)
COMMIT
Si vous générez les ids de cette façon, rassurez-vous, vous ne serez jamais à vous soucier de manquer. Par curiosité, j'ai effectué un test rapide pour savoir avec certitude à quelle profondeur vous pouvez aller. Voici un script de test:
DECLARE
@parent hierarchyid,
@child hierarchyid,
@high hierarchyid,
@cnt int
SET @parent = '/1/'
SET @child = @parent.GetDescendant(NULL, NULL)
SET @cnt = 0
WHILE (@@ERROR = 0)
BEGIN
SET @cnt = @cnt + 1
PRINT CAST(@cnt AS varchar(10)) + ': ' + @child.ToString()
SET @high = @parent.GetDescendant(@child, @high)
SET @child = @parent.GetDescendant(@child, @high)
END
Vous pouvez voir l'erreur en un point nichant niveau de 1426, de sorte que est votre limite pire cas pour nombre « entre » nœuds vous pouvez créer, pire des cas ce qui signifie que chaque insertion entre les deux nœuds les plus imbriqués.
Comme je l'ai mentionné dans les commentaires, il est assez difficile d'atteindre cette limite, mais cela ne fait toujours pas une bonne idée d'essayer. La longueur réelle des octets devient plus longue à mesure que vous utilisez de plus en plus de «points», ce qui dégrade les performances. Si le est votre index en cluster, cela va tuer les performances par des divisions de page. Si vous essayez de classer les nœuds par parent puis utilisez plutôt une colonne de classement; c'est plus facile et plus efficace pour trier d'un SELECT
plus tard que de faire au cours de votre INSERT
où vous devez vous soucier de l'isolation des transactions et d'autres maux de tête de ce type.
Mon application maintient les classements. En fait, je n'ai pas besoin de barres obliques "/" sur mes chemins. L'insertion entre les éléments existants est la clé. –
@Bruno: Vous ne devriez vraiment pas penser 'hierarchyid' comme un moyen de maintenir un ordre spécifique d'enfants. Oui c'est * capable * de le faire, mais ce n'est pas * optimisé * pour ce cas-là. Si vous voulez des classements, ajoutez une colonne de classement. (PS Je ne suis pas sûr de ce que vous voulez dire quand vous dites que vous n'avez pas besoin de slash - il n'y a pas de "slashs" * dans un hierarchyid, c'est juste la représentation de la chaîne.) – Aaronaught
Quel type suggérez-vous? utiliser pour les classements, permettant l'insertion entre n'importe quelle paire? –