我正在尝试设计一个数据库,我的一个表是这样的:
表 player_in_tournament :
import { Component } from '@angular/core';
import { ROUTER_DIRECTIVES } from '@angular/router';
import {Http} from '@angular/http';
import { CookieService } from 'angular2-cookie/services/cookies.service';
import { FORM_PROVIDERS } from '@angular/forms';
import { TRANSLATION_PROVIDERS} from '../../translate/translation';
import { TranslateService } from '../../translate/translate.service';
import { TranslatePipe } from '../../translate/translate.pipe';
@Component({
selector: 'my-app',
template:
`<div>
<router-outlet></router-outlet>
<app-dashboard></app-dashboard>
<app-login></app-login>
</div>`,
directives: [ROUTER_DIRECTIVES],
pipes: [TranslatePipe],
providers: [CookieService, FORM_PROVIDERS, TRANSLATION_PROVIDERS, TranslateService],
})
export class AppComponent {
public constructor(private http: Http, private _translate: TranslateService) {
/* Setting default lanaguage. */
switch(navigator.language) {
case 'de' : {
_translate.use('de');
break;
}
default: {
_translate.use('en');
}
}
}
public requestAPI = function() {
return this.http;
}
}
并且PK由两个第一列组成。
在表ID_tourn | ID_player | and other attributes...
(表示比赛的比赛/比赛)中,我想引用player_in_tournament中的2个“对象”,所以我应该有两个外键,每个外键由一个ID_player和ID_tour。
但tournament_game
在两个“对象”中都是相同的。
问题是,更改第一个表的PK并添加ID_tour
是否是个好主意,并在ID_player_in_tournament
表中使用它作为外键。
答案 0 :(得分:1)
向player_in_tournament
表添加代理键可以构建代表具有两个不同tournament_game
的玩家的ID_tourn
。这样可以避免冗余,但会造成不一致。
您应该有三个字段参与两个外键 -
(ID_tourn, ID_player1)
代表第一个player_in_tournament
行(ID_tourn, ID_player2)
代表第二个player_in_tournament
行请注意,同一列ID_tourn
参与两个外键关系:
create table player_in_tournament(
ID_tourn int
, ID_player int
, ...
, primary key(ID_tourn, ID_player)
);
create table tournament_game(
ID_tourn int
, ID_player1 int
, ID_player2 int
, ...
, foreign key (ID_tourn, ID_player1)
references player_in_tournament(ID_tourn, ID_player)
, foreign key (ID_tourn, ID_player2)
references player_in_tournament(ID_tourn, ID_player)
);
答案 1 :(得分:1)
首先,你有一场锦标赛。您已经为它提供了一个名为ID_tourn的人工识别器。这可能是因为没有像锦标赛2016Q3那样的真实姓名或号码。 (如果是的话,你可以使用这个锦标赛号码并且不必人工添加ID。)
然后你有球员。在这里,您再次创建一个ID。可能是因为他们是现实生活中没有任何自然识别号码的玩家。 (如果他们只是你游戏中的玩家,他们会有一个你可以使用的登录名或用户名。)
现在你有参加比赛的球员。记录由锦标赛标识符和玩家标识符自然识别。
最后你有一个锦标赛游戏,显然是两个锦标赛玩家的比赛。因此,记录将包含锦标赛标识符和两个玩家标识符。它将包含两个外键:ID_tourn + ID_player1和ID_tourn + ID_player2。
所有这些,在可能的情况下使用复合键和自然键(如登录名)是创建数据库的一个概念。另一个是为每个表提供一个人工ID和链接表。我曾在大型数据库上工作过,并且更喜欢第一个概念,但还有其他人喜欢全ID的概念。
这是两个比较的例子。 PK =主键,FKn =外键,PK2 =唯一约束(如第二个PK)
自然键/复合键
人工ID
答案 2 :(得分:0)
正如你所猜测的那样,这将使表tournament_game
中的外键只有两列宽而不是四列,这将提高你需要在SQL语句中编写的连接的便利性和可读性。唯一的缺点是表宽度的增加,但每行只有几个字节。正如您所知,这被称为代理键&#34; (而不是&#34;自然键&#34;)。
如果这样做,请确保在&#34;自然键&#34;上留下唯一的键或约束。 (ID_tourn, ID_player
)确保这两个字段保持唯一性并且表保留数据一致性。
答案 3 :(得分:0)
这里有2个表table_in_tournament和tournament_game。顾名思义,tournament_game是游戏中锦标赛的表格,因此它应该有锦标赛ID和锦标赛名称以及与锦标赛相关的所有其他属性。另一个表player_in_tournament应该有玩家ID,玩家名称和锦标赛ID(来自tournament_game表的参考)以及与玩家相关的其他属性。这应该根据您的查询进行设计。