数据库设计:有没有比3字段复合主键更好的方法?

时间:2010-12-13 02:17:24

标签: database-design

我正在尝试为一个夜总会建立数据库模型,这个夜总会有几个地点,有几个场地。我在我的数据库中创建了3个表

Venues
Bands
VenueSchedule

我认为VenueSchedule将是这些之间的连接表,主键是venue_idband_id,这样你就可以查找哪个乐队在哪个场地播放了。但是皱纹是我还需要能够查询乐队在该场地上播放的时间,以及哪些乐队将在特定日期在特定场地上播放。

VenueSchedule表的主键现在有2个字段。如果我将date字段添加到主键中,这是不好的做法吗?还有比这更好的方法吗?

5 个答案:

答案 0 :(得分:3)

我不会这样做。我会使用代理键(如SQL Server中的Identity)。代理将更快检索,并且您的FK表将更高效和更小,因为您不需要将这三列添加到每个FK表。在大多数情况下,我是使用代理人的忠实粉丝,尽管数据库纯粹主义者会强烈不同意,因为代理与表中的其他列没有任何关系,IOW,它是一个严格用于PK的人工专栏。我理解这个位置,但我还是使用它们并推荐它们。

答案 1 :(得分:3)

您比我更了解您的数据,但在我看来(venue_id,band_id,date)将是VenueSchedule最可能的关键。 (venue_id,band_id)意味着每个乐队只能播放一次,或者不需要该日期。

我建议您对其他回复中使用的代理密钥保持谨慎。首先,代理键不会与复合键完成相同的工作:它不会保持数据完整性,因为代理不会停止同一场地,乐队,日期组合被多次插入。这会产生潜在的更新异常,并可能导致不准确的结果。

其次,根据给出的信息,为什么你甚至需要一个代理密钥或如何使用它是不明显的。 如果该表在其他地方被引用,那么可能想要使用代理 - 但如果您没有使用它,那么代理键只会是额外的权重,存储和索引的复杂性根本没有任何好处。

答案 2 :(得分:2)

虽然代理键(Id)很受欢迎,但我倾向于在“依赖实体”中避免它们,因为复制数据非常容易。如果我要在ID表中添加Schedule,则(VenueId, BandId, Date, Status)上需要一个唯一约束,它会为数据库添加另一个索引。

我添加了Status字段以允许取消演出。

alt text

答案 3 :(得分:1)

我会使用代理主键和唯一约束。

答案 4 :(得分:1)

听起来更像是获取数据而不是存储的问题。设置视图以提供所需的数据,或使用数据仓库以非规范化方式存储数据是报告需求的一种选择。

对于存储,如上所述,我建议使用具有人工主键的表,此表指向其他三个引用(场所,乐队和场地),因此一个表将三者连接在一起,这样方式,您可以使用此链接编写查询,该查询链接到其他三个以获取数据。