【发布时间】:2011-08-24 22:25:49
【问题描述】:
我正在开展一个具有以下目标的项目:用户可以创建一个挑战并选择一个可选的竞争对手来参加这个挑战。挑战会生成每日条目,并将跟踪这些条目的统计数据。
基本的 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 等)创建两个表。
第二种方法解决了这个问题,并且具有一些优势,例如将来允许多个竞争对手。但是,我不能再用这种方法做的一件事是在单个用户而不是整个挑战表中强制挑战名称唯一性。此外,寻找挑战所有者等任务现在变得更加棘手。
挑战表的正确方法是什么?无论如何以开发人员友好的方式设置这些表,还是我应该一直跳到类表继承并在那里管理所有者/竞争对手的概念?
【问题讨论】:
-
您使用的是什么数据库?我们一直在 SQL Server 中对同一个 pk 字段执行多个外键。这消除了您对第一种方法的反对。如果您需要超过 2 个人参与挑战,则第二种方法可能仍然更好。
-
他真正反对的不是为同一个 pk 字段设置多个 fk(他无论如何都在这样做),而是将单个 fk 字段设置为多个 pk。我认为这在任何情况下都是不可能的,除了相当有问题......
-
我经常在 SQL Server 中使用触发器来强制执行特殊的唯一性要求,例如“用户名”只需要在活动帐户中是唯一的。
标签: sql schema one-to-many one-to-one class-table-inheritance