我有一个包含列的表
id, playername, sport1, sport2
但是,我的要求是说玩家可以拥有n个体育项目,因此需要一个多值列“体育”,否则我将使用sport3,sport4等等。如何更改表格以结合sport1,sport2并将其用作新行的多值列?
答案 0 :(得分:4)
经典的解决方案是拥有第二个表,其中包含playerId和sport的列。然后,要查看玩家所拥有的所有体育项目,请加入两者。
答案 1 :(得分:0)
sqlite不支持多值字段。我所知道的唯一可以做到这一点的DBMS是Microsoft Access,但我一般不会建议从sqlite切换到Access,即使你保证只在Windows计算机上运行。
这是数据库设计的经典问题。我建议您从单个表切换到多个表,以便在数据库中准确描绘每个实体类型。例如,运动的名称不是运动员的属性,它是运动的属性,因此您可能需要运动表。你显然需要一个播放器表。由于玩家可以进行多项运动,并且每项运动可能由多个运动员进行,因此您有many-to-many relationship。这可以使用带有外键的多个表在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
)
)
这种结构是通过database normalization的过程实现的。
您现在可以获得玩家所有运动的列表,
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-injection安全漏洞。