2011-12-02 4 views
1

Trois tables.index unique à travers rejoindre?

événement a beaucoup de courses

Race a beaucoup d'inscriptions

Inscriptions a un entier sur ce bib_number '

Ce que je dois faire en sorte que le numéro de dossard est unique à l'événement.

La meilleure solution est je dénormaliser event_id sur les inscriptions ... je pourrais ajouter une clé unique aux enregistrements:

UNIQUE KEY `index_bib_number_event_id` (`bib_number`, `event_id`) 

.... mais je préfère éviter que, si possible,

Voici les tableaux:

CREATE TABLE `registrations` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `race_id` int(11) NOT NULL, 
    `bib_number` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
) 

CREATE TABLE `races` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `event_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`) 
} 

CREATE TABLE `events` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    PRIMARY KEY (`id`) 
} 
+0

Vous ne savez pas si c'est possible (c'est pourquoi c'est un commentaire pas une réponse) mais avez-vous essayé de créer un index unique sur une vue? –

+0

Le numéro de dossard est-il unique à l'événement, et non à la course? –

+0

@Catcall, l'OP veut s'assurer que le numéro de dossard est unique à l'événement * entier *, et pas seulement à la course. –

Répondre

0

vous voyez .. vous dénormaliser déjà votre table registration parce bib_number ne dépend pas de PK (id) . Donc, vous pouvez vous sentir libre de passer event_id à registration mais je préfère jeter un oeil sur le modèle db une fois de plus et essayer de trouver est-ce bien. Peut-être avez-vous manqué quelque chose lors de la conception de DB.

0

Quelque chose dans ce sens devrait fonctionner. Je suis sûr que vous pouvez réparer la syntaxe pour MySQL.

J'ai omis les numéros automatiques, car ils peuvent cacher ce qui se passe réellement. Toutes les tables sont au moins 5NF, un fait que vous pourriez négliger si vous utilisez des numéros auto-incrémentés.

create table events (
    event_id integer primary key 
); 

create table races (
    event_id integer not null references events (event_id), 
    race_id integer not null, 
    primary key (event_id, race_id) 
); 

create table registrations (
    event_id integer not null, 
    race_id integer not null, 

    foreign key (event_id, race_id) 
    references races (event_id, race_id), 

    registration_id integer not null, 
    primary key (event_id, race_id, registration_id), 

    bib_number integer not null, 

    unique (event_id, bib_number) 
); 

Voici quelques exemples de données à utiliser.

-- Two events. 
insert into events values (1); 
insert into events values (2); 

-- Three races in each event. 
insert into races values (1,1); 
insert into races values (1,2); 
insert into races values (1,3); 
insert into races values (2,1); 
insert into races values (2,2); 
insert into races values (2,3); 

-- Some registrations. 
insert into registrations values (1, 1, 1, 51); 
insert into registrations values (1, 1, 2, 52); 
insert into registrations values (1, 1, 3, 53); 
insert into registrations values (1, 1, 4, 54); 
insert into registrations values (1, 2, 1, 61); 
insert into registrations values (1, 2, 2, 62); 
insert into registrations values (1, 2, 3, 63); 
insert into registrations values (1, 2, 4, 64); 
insert into registrations values (1, 3, 1, 71); 
insert into registrations values (1, 3, 2, 72); 
insert into registrations values (1, 3, 3, 73); 
insert into registrations values (1, 3, 4, 74); 

-- These bib numbers were already used, but not in event 2. 
insert into registrations values (2, 1, 1, 51); 
insert into registrations values (2, 1, 2, 52); 
insert into registrations values (2, 1, 3, 53); 
insert into registrations values (2, 1, 4, 54); 
+0

'clé primaire (event_id, race_id, registration_id)' semble redondant. Soit '(event_id, race_id)' ou '(registration_id)' peut être une clé primaire pour la table 'enregistrements '. C'est le dernier dans le schéma de l'OP, mais, comme vous ajoutez la colonne 'event_id' à la table' registrations', une colonne d'ID dédiée peut s'avérer totalement inutile. Qu'est-ce que tu penses? –

+0

@AndriyM: C'est difficile à dire, car nous n'avons pas de données réelles en plus du numéro de dossard. Normalisation, identification des clés candidates, dépendances fonctionnelles - celles-ci ont toutes à voir avec des attributs réels et des données réelles, et non avec des numéros d'identification de substitution. En l'état, {event_id, race_id} n'est pas suffisant pour identifier une ligne dans les enregistrements, mais {event_id, race_id, bib_number} l'est. (De plus, vous pouvez ajouter d'autres attributs réels aux "événements" de telle sorte que ce soit seulement en 2NF au lieu de 5NF.) –

+0

Hm, vous avez bien sûr raison, et je me demande comment j'ai pu trouver cette idée idiote. J'aurais peut-être eu quelque chose de différent à l'esprit, cependant, si c'est le cas, je ne peux pas me souvenir maintenant de ce que c'était. Peut-être que je pensais que 'race_id' était redondant au lieu de' registration_id', mais je ne suis pas sûr.En tout cas, désolé de vous déranger. –

Questions connexes