我有一个有列的表
id, playername, sport1, sport2
但是,我的要求是一个玩家可以拥有 n 项运动,因此需要一个多值列“运动”,否则我将使用运动 3、运动 4 等等。如何更改表以组合运动 1、运动 2 并将其用作未来新行的多值列?
经典的解决方案是使用第二个表,其中包含 playerId 和运动的列。然后,要查看玩家拥有的所有运动项目,请加入两者。
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 注入安全漏洞的影响。