Mysql 跨联接的唯一索引?
三张桌子 这个项目有很多比赛 这个种族有许多注册 注册上有一个整数“bib_number” 我需要的是确保bib编号是活动的唯一编号 我的最佳解决方案是将事件id反规范化到注册上。。。然后我可以为注册添加一个唯一的密钥:Mysql 跨联接的唯一索引?,mysql,sql,ruby-on-rails,Mysql,Sql,Ruby On Rails,三张桌子 这个项目有很多比赛 这个种族有许多注册 注册上有一个整数“bib_number” 我需要的是确保bib编号是活动的唯一编号 我的最佳解决方案是将事件id反规范化到注册上。。。然后我可以为注册添加一个唯一的密钥: UNIQUE KEY `index_bib_number_event_id` (`bib_number`, `event_id`) ……但如果可能的话,我宁愿避免这样做 以下是表格: CREATE TABLE `registrations` ( `id` int(11)
UNIQUE KEY `index_bib_number_event_id` (`bib_number`, `event_id`)
……但如果可能的话,我宁愿避免这样做
以下是表格:
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`)
}
你看。。您已经取消了
注册
表的规范化,因为bib_编号
不依赖于PK(id)。所以,您可以随意将事件id
移动到注册
,但我更愿意再次查看db模型,并尝试找出它是否合适。在设计数据库的过程中,您可能遗漏了一些东西。按照这些思路应该可以工作。我相信你可以修改MySQL的语法
我省略了自动编号,因为它们可以隐藏真正发生的事情。所有的表都至少有5NF,如果使用自动递增的数字,您可能会忽略这一事实
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)
);
下面是一些示例数据
-- 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);
不确定这是否可行(这就是为什么这是一个评论而不是答案),但您是否尝试过在视图上创建一个唯一的索引?Bib编号对事件是唯一的,而不是对比赛?@Catcall,OP希望确保Bib编号对整个事件是唯一的,而不仅仅是对比赛。@MarkBannister:我知道他说了什么。我怀疑他是否真的是这个意思。@MarkBannister:是的。我的思想和写作正从相反的方向朝着同一点前进。我的回答是基于它对事件是唯一的。
主键(事件id、种族id、注册id)
似乎是多余的。(事件id、比赛id)
或(注册id)
可以是注册
表的主键。它是OP模式中的后者,但是,当您将event\u id
列添加到registrations
表中时,可能完全不需要专用的id列。你觉得怎么样?@AndriyM:很难说清楚,因为除了围嘴号码之外,我们没有任何真实的数据。规范化、候选键的识别、功能依赖——这些都与真实属性和真实数据有关,而不是与代理id号有关。目前,{event_id,race_id}不足以识别注册中的行,但是{event_id,race_id,bib_number}是。(另外,你可以在“事件”中添加其他真实属性,使其仅在2NF中而不是在5NF中。)嗯,你当然是对的,我想知道我是如何想出这个愚蠢的想法的。我可能有不同的想法,但是,如果是这样,我现在不记得是什么了。也许我在想race\u id
是多余的,而不是registration\u id
,但我不确定。无论如何,很抱歉打扰你。