2010-06-08 17 views
4

J'ai une table qui contient des catégories imbriquées. Je veux éviter les noms en double sur les éléments de même niveau (c'est-à-dire, les catégories avec le même parent). Je suis venu avec ceci:Contrainte unique avec colonne nullable

CREATE TABLE `category` (
    `category_id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `category_name` varchar(100) NOT NULL, 
    `parent_id` int(10) unsigned DEFAULT NULL, 
    PRIMARY KEY (`category_id`), 
    UNIQUE KEY `category_name_UNIQUE` (`category_name`,`parent_id`), 
    KEY `fk_category_category1` (`parent_id`,`category_id`), 
    CONSTRAINT `fk_category_category1` FOREIGN KEY (`parent_id`) REFERENCES `category` (`category_id`) ON DELETE SET NULL ON UPDATE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci 

Serve, category_name_UNIQUE n'impose pas ma règle pour les catégories de niveau racine (ceux où parent_id est NULL). Y a-t-il une solution de contournement raisonnable?

Répondre

5

solution raisonnable pourrait inclure

  • la vérification des contraintes avec des déclencheurs si les opérations de mise à jour/insertion ne sont pas critiques pour la vitesse
  • en utilisant une sorte de valeur spéciale pour indiquer nulle; cela pourrait être modélisé relativement correctement - un nœud racine avec id 0 qui ne sera jamais supprimé, ont PARENT_ID DEFAULT 0 et ON DEFAULT SUPPRIMER SET
+0

Non 'ON DELETE SET DEFAULT' dans MySQL, j'ai peur :( –

+0

Ah, en effet ... reconnu par l'analyseur, mais rejeté:" SET DEFAULT: Cette action est reconnue par l'analyseur, mais InnoDB rejette la table définitions contenant les clauses ON DELETE SET DEFAULT ou ON UPDATE SET DEFAULT. "Eh bien, vous pouvez implémenter la cascade dans les triggers – Unreason

+0

Les triggers dans MySQL ne sont pas autorisés à modifier d'autres lignes de la table affectée –

2

Pour autant que je peux voir, à appliquer est du côté de la base de données, possibilités:

  1. Définir un nœud 'racine', ne fait qu'ajouter au noeud racine est autorisé, pas'new » rootNode, ou
  2. Ajouter un avant insertion de avant la mise à jour trirgger

BTW: sur la catégorie de suppression parente les ories sont promues aux catégories de racine, est-ce cela que vous voulez?

+0

«sur les catégories de suppression parent sont promus à des catégories de racine, c'est ce que vous voulez?» - Réponse courte, oui. Je vais probablement le changer au fur et à mesure du développement mais je suppose que je dois écrire un trigger si je veux que MySQL le gère pour moi. –

+0

Je pense que je vais juste autoriser les dupes au niveau de la racine. Cela simplifie le code de suppression de toute façon. –