0

我有一个有列的表

id, playername, sport1, sport2

但是,我的要求是一个玩家可以拥有 n 项运动,因此需要一个多值列“运动”,否则我将使用运动 3、运动 4 等等。如何更改表以组合运动 1、运动 2 并将其用作未来新行的多值列?

4

2 回答 2

4

经典的解决方案是使用第二个表,其中包含 playerId 和运动的列。然后,要查看玩家拥有的所有运动项目,请加入两者。

于 2013-05-30T15:19:47.033 回答
0

sqlite 不支持多值字段。我知道的唯一可以做到这一点的 DBMS 是Microsoft Access,但我一般不建议从 sqlite 切换到 Access,即使您保证只能在 Windows 计算机上运行。

这是数据库设计的经典问题。我建议您从单个表切换到多个表,以便在数据库中准确描绘每种实体类型。例如,一项运动的名称不是运动员的属性,而是一项运动的属性,因此您可能需要一个运动表。您显然需要一个 Player 表。而且由于玩家可以参加多项运动,并且每项运动都可能由多个玩家参加,因此您具有多对多的关系。这可以在 RDBMS 中使用具有外键的多个表进行建模。

考虑以下数据库结构(将其视为伪代码,尽管它可能按原样工作)。

CREATE TABLE Player (
    PlayerId int NOT NULL PRIMARY KEY,
    Name string NOT NULL UNIQUE
)

CREATE TABLE Sport (
    SportId int NOT NULL PRIMAEY KEY,
    Name string NOT NULL UNIQUE
)

CREATE TABLE PlayerSport (
    PlayerId int NOT NULL FOREIGN KEY REFERENCES Player (PlayerId),
    SportId int NOT NULL FOREIGN KEY REFERENCES Sport (SportId),
    PRIMARY KEY (
        PlayerId,
        SportId
    )
)

这种结构是通过数据库规范化过程产生的。

你现在可以得到一个球员所有运动的列表,

SELECT
    Sport.Name
FROM Sport
    INNER JOIN PlayerSport ON PlayerSport.SportId = Sport.SportId
        AND PlayerSport.PlayerId = @PlayerId
ORDER BY
    Sport.Name

或者所有运动员的一项运动,

SELECT
    Player.Name
FROM Player
    INNER JOIN PlayerSport ON PlayerSport.SportId = Player.PlayerId
        AND PlayerSport.SportId = @SportId
ORDER BY
    Player.Name

或者所有的球员和运动,

SELECT
    Player.Name AS Player,
    Sport.Name AS Sport
FROM Player
    INNER JOIN PlayerSport ON PlayerSport.SportId = Player.PlayerId
    INNER JOIN Sport ON Sport.SportId = PlayerSport.SportId
ORDER BY
    Player.Name,
    Sport.Name

但请注意,此最终查询的结构与您的原始表不同。在静态 SQL 中不可能为每个球员输出一行,为每个运动输出一列。您可以构建一个动态查询,但这并不容易,容易出错,并且容易受到 sql 注入安全漏洞的影响。

于 2013-05-30T15:29:15.690 回答