我正在开发一个具有以下目标的项目:用户可以创建挑战并选择一个可选的竞争对手来参与这一挑战。挑战赛会生成每日参赛作品,并会跟踪这些参赛作品的统计数据。
基本的用户和条目实体如下所示:
CREATE TABLE users (
id (INT),
PRIMARY KEY (id)
);
CREATE TABLE entries (
challengeId INT,
userId INT,
entryDate DATE,
entryData VARCHAR,
PRIMARY KEY (challengeId, userId, entryDate)
)
我遇到麻烦的是与Rival概念的挑战赛。我可以看到两种方法。
// 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和rivalId)。为了设置外键,我必须为所有内容(owner_entries,rival_entries,owner_stats等)创建两个表。
第二种方法解决了这个问题,并且具有一些优势,例如将来允许多个竞争对手。但是,使用该方法我不能再做的一件事是在单个用户而不是整个Challenge表中强制执行Challenge名称唯一性。此外,找到挑战者所有者的任务现在变得更加棘手。
挑战表的正确方法是什么?无论如何以开发人员友好的方式设置这些表,还是我应该一直跳到类表继承并管理那里的所有者/竞争对手的概念?
答案 0 :(得分: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))
这样可以轻松跟踪谁拥有挑战,然后提取个人参与者
这样您还可以安全地使用所有者唯一标识挑战名称,并且userId
中participant
上的外键很容易。然后,“竞争对手”就是不挑战所有者的所有参与者。
答案 1 :(得分:0)
我认为第一种方法是正确的。 您可以为用户提供一个表,为挑战提供一个表。
您是否知道可以像下面一样两次引用一张表?
SELECT * FROM CHALLENGES
INNER JOIN USERS AS OWNERS ON OWNERS.ID = CHALLENGES.OWNERID
INNER JOIN USERS AS RIVALS ON RIVALS.ID = CHALLENGES.RIVALID
在这种情况下,您可以在不创建新表的情况下引用竞争对手和所有者。