1

我正在开展一个具有以下目标的项目:用户可以创建一个挑战并选择一个可选的竞争对手来参加这个挑战。挑战会生成每日条目,并将跟踪这些条目的统计信息。

基本的 User 和 Entry 实体如下所示:

CREATE TABLE users (
    id (INT),
    PRIMARY KEY (id)
);

CREATE TABLE entries (
    challengeId INT,
    userId INT,
    entryDate DATE,
    entryData VARCHAR,
    PRIMARY KEY (challengeId, userId, entryDate)
)

我遇到问题的作品是具有竞争对手概念的挑战作品。我可以看到两种方法。

// Hard code the concept of a Challenge Owner and Rival:
CREATE TABLE challenges (
    id INT,
    name VARCHAR,
    ownerId INT,
    rivalId INT NULL,
    PRIMARY KEY (id),
    UNIQUE KEY (ownerId, name)
);

// Create Many-to-one relationship.
CREATE TABLE challenges (
    id INT,
    name VARCHAR,
    PRIMARY KEY (id),
    UNIQUE KEY (name)
)
CREATE TABLE participant (
    challengeId INT,
    userId INT,
    isOwner BIT,
    PRIMARY KEY (challengeId, userId)
)

第一种方法的问题是参照完整性很难,因为现在有两列 userId 驻留(ownerId 和 CompetitionId)。为了设置外键,我必须为所有内容(owner_entries、competitive_entries、owner_stats 等)创建两个表。

第二种方法解决了这个问题,并且具有一些优势,例如将来允许多个竞争对手。但是,我不能再用这种方法做的一件事是在单个用户而不是整个挑战表中强制挑战名称唯一性。此外,寻找挑战所有者等任务现在变得更加棘手。

挑战表的正确方法是什么?无论如何以开发人员友好的方式设置这些表,还是我应该一直跳到类表继承并在那里管理所有者/竞争对手的概念?

4

2 回答 2

1

我认为我设置它的方式如下(使用第二种方法):

CREATE TABLE challenges (id INT, 
                         name VARCHAR, 
                         owner_id INT, 
                         PRIMARY KEY (id),
                         UNIQUE KEY (name, owner_id))

CREATE TABLE participant (challengeId INT,
                          userId INT, 
                          PRIMARY KEY (challengeId, userId))

这允许轻松跟踪拥有挑战,但提取出单个参与者。
这也将允许您安全地由所有者唯一的挑战名称,并且在其中的外键userIdparticipant容易。'竞争对手'是所有不是挑战所有者的参与者。

于 2011-08-24T22:41:38.610 回答
0

I treat the first approach the right one. You could have one table for users and one for challenges.

Are you aware that you can reference one table twice like below?

SELECT * FROM CHALLENGES 
INNER JOIN USERS AS OWNERS ON OWNERS.ID = CHALLENGES.OWNERID
INNER JOIN USERS AS RIVALS ON RIVALS.ID = CHALLENGES.RIVALID

In this case you can reference both rivals and owners without creating new tables.

于 2011-08-24T22:33:33.973 回答