2011-10-20 4 views
2

Je tente d'implémenter une structure de table "extension" pour certaines statistiques que je rassemble de plusieurs sources.Dilemme MySQL: clé unique composite à travers les tables

Ma table "parent" ressemble à ceci:

`test_parent` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `date` date NOT NULL, 
    `actions` int(11) unsigned NOT NULL, 
    PRIMARY KEY (`id`) 
) 

Ma première table "enfant" semble somethinglike ce (finalement je vais avoir une table enfant pour chaque source):

`test_child` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `test_parent_id` int(11) unsigned NOT NULL, 
    `external_id` int(11) NOT NULL, 
    `external_actions` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `test_parent_id` (`test_parent_id`) 
) 
CONSTRAINT `test_child_ibfk_1` FOREIGN KEY (`test_parent_id`) REFERENCES `test_parent` (`id`) 

Tout cela fonctionnera très bien dans ma mise en œuvre (j'utiliserai Java/Hibernate); cependant, pour la première table enfant, j'ai besoin d'une clé composite unique pour external_id et date. Je sais que je ne peux pas avoir une clé composite unique entre les tables. Je préférerais ne pas avoir une seule table pour stocker toutes les statistiques parce que les analyses réelles que je collectionne peuvent varier considérablement selon la source. Je serais plus ouvert à se débarrasser de la table "parent".

Existe-t-il une autre façon de voir ce problème? J'espère éviter d'utiliser des déclencheurs pour imposer l'unicité, si possible.

Répondre

3

Vous avez besoin du date dans la table d'enfant si vous souhaitez établir une contrainte unique avec external_id. Vous pouvez également avoir date vivre dans la table parente, et le référencer via la clé étrangère. Cela vous permettra de supporter différemment date par d'autres tables enfants dans le futur.

CREATE TABLE `test_parent` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
    `date` date NOT NULL, 
    `actions` int(11) unsigned NOT NULL, 
    PRIMARY KEY (`id`, `date`) 
); 

CREATE TABLE `test_child` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `test_parent_id` int(11) unsigned NOT NULL, 
    `date` date NOT NULL, 
    `external_id` int(11) NOT NULL, 
    `external_actions` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `test_parent_id` (`external_id`,`date`), 
    CONSTRAINT `test_child_ibfk_1` FOREIGN KEY (`test_parent_id`, `date`) 
    REFERENCES `test_parent` (`id`,`date`) 
); 
-1

Déplacer le champ date à la table des enfants et déclarer une clé unique:

ALTER TABLE child ADD UNIQUE INDEX parent_date (parent_id, `date`); 
+0

Je préfère ne pas, tous les enfants auraient besoin de date. Mais cela peut être un compromis raisonnable entre ce que je veux idéalement et complètement axer la table parent. – smp7d