相似数据的规范化与非规范化数据库
Normalised vs. denormalised database for similar data
我打算建立一个数据库,用于存储大量有关音乐的数据。
我将 song-specific 信息存储在 db_song
table 中。
我还想存储 genres、instruments、samples 和 playlists。
因为一首歌可以有多种流派、乐器、样本和播放列表,所以大问题是:
这样做更有意义吗:
- 将所有这 4 个数据存储在单独的 tables
中
- 将所有这 4 个数据存储在一个 table 中,并在单独的列中记录 type
数据库会经常更新,但用户会更频繁地请求数据。
感谢您的帮助。
编辑:
正如 Amit 所建议的,使用上面的设置,会有很多重复数据。
如何在不同的 table 中存储流派和乐器值以及播放列表标题,在另外 3 table 中存储流派、乐器和播放列表关系(项目到歌曲)。
所以新场景:
- 将所有这 4 个数据存储在单独的 tables + 4 个 tables 中以存储 item-to-song 关系
- 将所有这 4 个数据存储在一个 table 中,并在单独的列中记录 类型 + 在另一列中记录与歌曲的关系
当您说 "large amount of data" 时,您指的是多少数据?几百万首歌曲和相关元数据不应该对标准数据库设置造成任何实际性能问题。
我建议以第三范式 (3NF) 设计您的数据库,从而使用 4 个或更多单独的 table。对于非规范化结构(一个大 table),行中将存在重复信息,与规范化结构相比,更新成本更高。
对于围绕数据的需求reads/analysis,如果需求是针对具有历史数据需求的复杂数据分析,那么值得考虑在操作系统之上构建数据仓库。如果数据要求很简单(在这些 table 之间加入以获得特定歌曲、艺术家或流派的信息),那么规范化数据库应该能够轻松地回答它们。
一个'song'可以有0个或1个或多个流派、乐器、样本和播放列表。因此 not 少于 5 table 是有意义的。
此外,其中许多是"many-to-many"。例如,一个播放列表可以有很多首歌曲;一首歌可以在多个播放列表中。要处理这种情况,您需要一个额外的 table 与 song_id 和 playlist_id 来建立多对多 'relationship'.
另一方面,"genre" 可能有十几种可能性——'rock'、'classical'、...您可能不需要 table流派。相反,每首歌曲(以及每个播放列表?)都可以包含一个带有流派的 ENUM 或 SET。多对多映射(在这种情况下)是不值得的。
为了充实架构,请考虑 SELECTs
的外观。
我打算建立一个数据库,用于存储大量有关音乐的数据。
我将 song-specific 信息存储在 db_song
table 中。
我还想存储 genres、instruments、samples 和 playlists。
因为一首歌可以有多种流派、乐器、样本和播放列表,所以大问题是:
这样做更有意义吗:
- 将所有这 4 个数据存储在单独的 tables 中
- 将所有这 4 个数据存储在一个 table 中,并在单独的列中记录 type
数据库会经常更新,但用户会更频繁地请求数据。
感谢您的帮助。
编辑:
正如 Amit 所建议的,使用上面的设置,会有很多重复数据。 如何在不同的 table 中存储流派和乐器值以及播放列表标题,在另外 3 table 中存储流派、乐器和播放列表关系(项目到歌曲)。
所以新场景:
- 将所有这 4 个数据存储在单独的 tables + 4 个 tables 中以存储 item-to-song 关系
- 将所有这 4 个数据存储在一个 table 中,并在单独的列中记录 类型 + 在另一列中记录与歌曲的关系
当您说 "large amount of data" 时,您指的是多少数据?几百万首歌曲和相关元数据不应该对标准数据库设置造成任何实际性能问题。
我建议以第三范式 (3NF) 设计您的数据库,从而使用 4 个或更多单独的 table。对于非规范化结构(一个大 table),行中将存在重复信息,与规范化结构相比,更新成本更高。
对于围绕数据的需求reads/analysis,如果需求是针对具有历史数据需求的复杂数据分析,那么值得考虑在操作系统之上构建数据仓库。如果数据要求很简单(在这些 table 之间加入以获得特定歌曲、艺术家或流派的信息),那么规范化数据库应该能够轻松地回答它们。
一个'song'可以有0个或1个或多个流派、乐器、样本和播放列表。因此 not 少于 5 table 是有意义的。
此外,其中许多是"many-to-many"。例如,一个播放列表可以有很多首歌曲;一首歌可以在多个播放列表中。要处理这种情况,您需要一个额外的 table 与 song_id 和 playlist_id 来建立多对多 'relationship'.
另一方面,"genre" 可能有十几种可能性——'rock'、'classical'、...您可能不需要 table流派。相反,每首歌曲(以及每个播放列表?)都可以包含一个带有流派的 ENUM 或 SET。多对多映射(在这种情况下)是不值得的。
为了充实架构,请考虑 SELECTs
的外观。