GraphQL 是一种用于前端开发的查询语言,通过它我们可以灵活地获取我们需要的数据,不必担心服务器返回冗余数据的问题。
但是,在使用 GraphQL 过程中,我们可能会遇到数据太过深层嵌套、重复请求等一系列问题。这时数据格式规范化就显得尤为重要,这样我们的代码可维护性更高,减少了出错的可能性。
数据规范化的思路
我们可以引入一个概念:归一化(Normalization)。它指的是将一段数据拆解成多个小的数据块,并且将这些小数据块统一地储存到一张表中,这样我们就可以根据小数据块的关系,来获取我们需要的数据。
GraphQL 中有一种操作叫 Fragments,它能够把查询分离成一些列的、可复用、可组合的模块。通过对 Fragment 的合理运用,我们可以构建出彼此独立的模块化组件。
实战示例
接下来,我们通过一个具体的示例来演示上述原理。假设我们现在正在打造一个音乐管理系统,每个音乐家可能会演唱多首歌曲,而我们需要查看该音乐家演唱过的每首歌曲的详细信息。
我们的查询语句可能是这样的:
-- -------------------- ---- ------- ----- --------------------------- --- - ------------ ------------- - ---- ----- - ----- ----- - ---- ----------- - - - -
通过上面的查询语句,我们就可以得到该音乐家的姓名、每首歌曲的详细信息以及每首歌的所在专辑的信息。但是,我们发现在每首歌曲信息的查询中,我们要查询 album 的每个字段信息,如果我们查询的歌曲数目很多,这将是一个很大的性能瓶颈。
这时,我们就可以走数据归一化的路线,对该数据进行规范化处理。
首先,我们可以把查询语句拆分成两部分,一个得到音乐家信息,一个得到每首歌曲的详细信息。
-- -------------------- ---- ------- ----- --------------------------- --- - ------------ ------------- - ---- ----- - -- - - - ----- --------------------------- ------ - ---------- ---------- - ----- -------- - -
注意到,SongDetailsQuery
中我们只查询了每首歌曲的必要信息,我们还用 album_id 来代替 album 的信息,因为 album 的详细信息已经在前面的查询中被获取过了。
接下来,我们将状态统一保存到一个表中,我们的表长这样:
-- -------------------- ---- ------- - ------------- - ------- ---- -------- ----------- ---------- --------- -- --------- - -------- --- ----- -- ----- ----------- --------- -- --------- - -------- ----------- ------ ----------- --------- -- ---------- - ------- ------ ------- -------------- ------------ -- ---------- - ------- ----------- -------------- ------------ - -
通过上面的数据表,我们可以轻松地得到我们需要的数据。我们通过一个查询函数来实现这个过程:
-- -------------------- ---- ------- -------- --------------- - ------ -------------------- - -------- ------------- - ------ ---------- -- ----------------- - -------- ------------ - ------ ----------------- - -------- ----------------------- - ------ ---------------------- -- - ------ - -------- ------ ----------------------- - -- -
通过这个查询函数,我们可以组合上面的两个查询,来得到我们需要的数据。
function getMusicianWithSongsAndAlbums(id) { const musician = getMusician(id) const songs = getSongsWithAlbums(musician.song_ids) return { ...musician, songs } }
这个函数接收一个音乐家的 id,然后返回该音乐家演唱的所有歌曲的详细信息,以及每首歌曲所在专辑的信息。此时,我们的数据就被成功地规范化了。
总结
在我们的实战示例中,我们将数据规范化分成两步来实现:
- 拆解查询语句,只获取必须的信息并走向数据库查询。
- 数据库返回归一化的数据表,并提供一个查询函数对查询结果进行组装。
通过上述的流程,我们成功地将数据规范化,提高了性能,也增强了代码的可读性和可维护性。对于龟毛的前端开发者而言,当然是非常具有指导意义的。
参考文献
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6478504e968c7c53b048ecaa