使用 MySQL 和 Node.js 从特定类别中获取每个项目的最佳做法是什么?

What is the best practice in getting each item from a specific category with MySQL and Node.js?

例如,我有一个table叫做相册

album_id 姓名 描述 价格 release_date
1 专辑1 描述1 10.00 当前日期
2 专辑2 描述2 10.00 当前日期
... ... ... ... ...

现在我有一个 table 叫做 songs

song_id 姓名 描述 持续时间 album_id
1 歌曲1 歌曲描述 1 180 1
1 歌曲2 歌曲描述 2 180 2
1 歌曲3 歌曲描述 3 180 2
1 歌曲4 歌曲描述 4 180 2

现在,我正在尝试构建一个 API 端点,其中我 return 所有专辑的 JSON,其中包括每张专辑中包含的歌曲列表。

目前,我可以先通过这个获取所有专辑:

let albums;
db.query('SELECT * FROM albums', (error, results) => {
    albums = results;
} 

这 return 是一个 JSON,其中包含所有专辑的详细信息。现在,我希望 JSON 中的每个条目都有一首歌曲 属性,其中包含属于该专辑的一组歌曲。

为此,我想过这样做

albums = albums.forEach(album => {
    let songs;
    db.query('SELECT * from songs WHERE album_id = ?', [album.album_id], (error, results) => {
        album.songs = results;
    }
}

我的预期输出是 JSON,其中包含第一个查询的所有属性和一个额外的“歌曲”属性,其中包含该专辑中每首歌曲的详细信息数组.

我认为这会完成我想做的事情,但有更好的方法吗?我觉得这不是最有效的方法。我是关系数据库的新手,所以我不确定如何完全关闭 SQL.

根据您设定的目标:

I'm trying to build an API endpoint where I return a JSON of all albums which includes a list of the songs that are included in each album.

执行此操作的最佳方法可能是使用 JOIN 查询、在数据库端创建的 VIEW 或在数据库端创建的 STORED PROCEDURE。您可以阅读有关 when/why to use each here.

的更多信息

所有这 3 个选项都可能 return 100% 的专辑及其相关歌曲数据,具体取决于您构建查询的方式。根据数据集的大小,stream the results.

可能是谨慎的做法

超出您设定的目标:

简单地提取所有数据(尤其是在添加嵌套数据时)并将其 return 发送到 API 端点的前端或使用者通常不是最佳做法。大型数据集可能会导致进程双方出现不良性能。

最好的方法是根据端点的使用和消费方式为您的 API 端点建模。在您提供的通用示例中,我们可能期望以下端点:

GET /api/list_albums
GET /api/get_album_by_id/1001
GET /api/list_songs_by_album_id/1001
GET /api/get_song_by_id/2001

作为您的 API 的用户,他们通过这些端点工作,他们获得越来越具体的结果。每个查询的结果包含可用于通知后续查询的数据。

如果我有一个包含 10,000 张专辑的数据库,我只需要查看其中一张的歌曲列表,我就可以查询该列表,找到我关心的专辑并使用其 ID 来查询其歌曲。

虽然需要两次查询,但节省了大量的数据聚合、传输和解析。

您可以在下面的链接中阅读有关 API 设计最佳实践的更多信息。这些可以帮助您思考如何为任何类型的解决方案构建最佳数据结构。

https://swagger.io/resources/articles/best-practices-in-api-design/

https://jsonapi.org/recommendations/