1

我为令人困惑的标题道歉,但我真的不知道如何用一句话来描述这个问题。

我有一个用于一般小费竞赛的 SQLite 数据库。对于不熟悉这个概念的人,人们会“提示”他们认为会在每轮体育比赛的每场比赛中获胜的人,并且在比赛结束时提示最正确的人获胜(奖品可能是金钱,骄傲, ETC)。AFL 在澳大利亚非常受欢迎。

基本结构是用户注册为所有者,然后他们可以创建任意数量的比赛,每个比赛都通过外键链接到他们。这是数据库模式的相关部分:

create table owner (
    owner_id INTEGER NOT NULL,
    owner_name VARCHAR NOT NULL,
    owner_nick VARCHAR UNIQUE NOT NULL,
    owner_email VARCHAR NOT NULL,
    owner_password VARCHAR NOT NULL,
    CONSTRAINT owner_pk PRIMARY KEY (owner_id)
);

create table comp (
    comp_id INTEGER NOT NULL,
    comp_owner_id INTEGER NOT NULL,
    comp_name VARCHAR UNIQUE NOT NULL,
    CONSTRAINT comp_pk PRIMARY KEY (comp_id),
    CONSTRAINT comp_owner_fk FOREIGN KEY (comp_owner_id) REFERENCES owner (owner_id) NOT DEFERRABLE
);

问题的要点是:我想对 comp 表的 comp_name 字段强制执行唯一约束(如上所示),因为单个所有者不应该有两个或多个同名比赛。但是,完全有可能两个不同的所有者想要两个名称相同的不同比赛(例如,两个办公室为同一个体育联盟举办小费比赛)。是否可以使用 SQL 强制执行此操作,还是我需要在其他地方手动执行?

几点注意事项:

  • 我正在使用 SQLite 3.6.20,它具有适当的外键约束执行
  • 该数据库永远不会在生产级应用程序中使用。这是一个私人项目。
  • 该数据库正在一个基于 Web 的 PHP 应用程序中使用。
  • 如果这不能用 SQLite 实现,那么用 MySQL 能实现吗?

编辑:我觉得我应该指出,我知道 SQLite 对更改表的支持非常有限,删除数据库并重新开始是一个非常好的选择。

4

2 回答 2

2

UNIQUE只需在这两个字段上创建一个约束,如下所示:

create table comp (
    comp_id INTEGER NOT NULL,
    comp_owner_id INTEGER NOT NULL,
    comp_name VARCHAR NOT NULL,
    CONSTRAINT comp_unq UNIQUE (comp_owner_id, comp_name),
    CONSTRAINT comp_pk PRIMARY KEY (comp_id),
    CONSTRAINT comp_owner_fk FOREIGN KEY (comp_owner_id) REFERENCES owner (owner_id) NOT DEFERRABLE
);

那应该做你想做的事。

于 2012-09-15T01:41:27.027 回答
1

您可以使用以下语法创建复合 UNIQUE 约束:

create table comp (
    comp_id INTEGER NOT NULL,
    comp_owner_id INTEGER NOT NULL,
    comp_name VARCHAR,
    CONSTRAINT comp_pk PRIMARY KEY (comp_id),
    CONSTRAINT comp_unique UNIQUE (comp_owner_id, comp_name),
    CONSTRAINT comp_owner_fk FOREIGN KEY (comp_owner_id) REFERENCES owner (owner_id) NOT DEFERRABLE
);

如果您担心将约束添加到已经存在的表中,您可以这样做:

 CREATE UNIQUE INDEX comp_unique (comp_owner_id, comp_name) ON comp

此外,您可以考虑丢失 owner_id 列并简单地使用 owner_name 作为所有者表中的主键。同样,您可能不需要 comp_id,因为您在该表中有另一个候选键。

于 2012-09-15T01:42:02.907 回答