1

Supposons que vous avez le tableau suivant, destiné à représenter des données hiérarchiques:Est-il possible d'utiliser des contraintes sur des données hiérarchiques dans un tableau auto-référentiel?

+--------+-------------+ 
| Field | Type  | 
+--------+-------------+ 
| id  | int(10)  | 
| parent | int(10)  | 
| name | varchar(45) | 
+--------+-------------+ 

Le tableau est autoréférentielle en ce que le parent_id fait référence à id.

Donc, vous pourriez avoir les données suivantes:

+----+--------+---------------+ 
| id | parent | name   | 
+----+--------+---------------+ 
| 1 |  0 | fruit   | 
| 2 |  0 | vegetable  | 
| 3 |  1 | apple   | 
| 4 |  1 | orange  | 
| 5 |  3 | red delicious | 
| 6 |  3 | granny smith | 
| 7 |  3 | gala   | 
+----+--------+---------------+ 

En utilisant MySQL, je suis en train d'imposer une (auto-référentiel) contrainte de clé étrangère sur les données en cascade sur la mise à jour et empêcher la suppression d'un enregistrer si elle a des "enfants".

J'utilise les éléments suivants:

CREATE TABLE `test`.`fruit` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, 
    `parent` INT(10) UNSIGNED, 
    `name` VARCHAR(45) NOT NULL, 
    PRIMARY KEY (`id`), 
    CONSTRAINT `fk_parent` 
    FOREIGN KEY (`parent`) 
    REFERENCES `fruit` (`id`) 
    ON UPDATE CASCADE 
    ON DELETE RESTRICT 
) 
ENGINE = InnoDB; 

D'après ce que je comprends, cela devrait répondre à mes besoins. (? Et parent doivent par défaut à null pour permettre des insertions, correcte)

Le problème est, si je change le id d'un enregistrement, il ne sera pas en cascade:

Cannot delete or update a parent row: a foreign key constraint fails (`test`.`fruit`, CONSTRAINT `fk_parent` FOREIGN KEY (`parent`) REFERENCES `fruit` (`id`) ON UPDATE CASCADE) 

Qu'est-ce que je manque?

N'hésitez pas à me corriger si ma terminologie est foirée ... Je suis nouveau pour les contraintes.

Répondre

2

Écart par rapport aux normes SQL: Si ON UPDATE CASCADE ou ON UPDATE SET NULL récursse pour mettre à jour la même table que celle précédemment mise à jour pendant la cascade, il agit comme RESTRICT. Cela signifie que vous ne pouvez pas utiliser les opérations auto-référentielles ON UPDATE CASCADE ou ON UPDATE SET NULL. Cela permet d'éviter les boucles infinies résultant des mises à jour en cascade. D'un autre côté, un auto-référentiel ON DELETE SET NULL est possible, tout comme un auto-référentiel ON DELETE CASCADE. Les opérations en cascade ne peuvent pas être imbriquées à plus de 15 niveaux de profondeur.