前端数据范式化

前言

现代web应用的飞速发展,特别是数据驱动思想指导下的React、vue等框架的出现,让咱们愈来愈须要关注数据的组织管理。随着应用复杂度的提高,若是不对数据进行有效合理的设计拆分,那么从性能、可维护性等方面来看会逐渐成为一种阻碍。因此咱们须要关注前端数据设计。html

其实没有一种很明确的规范告诉咱们具体到前端的数据结构应该如何去设计。关系数据库设计有不少范式,借鉴而不照搬结合前端自身特色,才是好的前端数据范式化的实践。前端

范式化

在深刻了解数据范式化以前,咱们能够先看个例子vue

举个栗子:

实际业务中,迭代比较多的业务,咱们通常会配置化,即除了业务数据以外将页面布局展现相关的内容也由接口控制。
那么后端返回的数据可能以下:git

{
    info: [
        {
            key:'a',
            txt:'展现1',
            value:0
        },
        {
            key:'b',
            txt:'展现2',
            value:1
        }
    ]
}

这样响应操做的时候,须要更新每一项的值若是直接修改info这个数组,存在着很大的不便。
若是你说还好,但这样将就操做以后,提交的时候发现这一大串冗余数据后端也不须要呀,仍是要处理value。
此时的数据还不是那么的复杂,不过层层嵌套的对象见过吧,让人心头一惊的数据格式,若是还在上面操做,可能下个迭代你本身都不知道到底该操做哪一个字段了。github

这时候若是将展现和逻辑相分离,抽出来一个专门的属性用来存放与后端交互的数据,看起来是简洁了一些,后期可维护性也加强了很多。web

{
    info: [
        {
            key:'a',
            txt:'展现1'
        },
        {
            key:'b',
            txt:'展现2'
        }
    ],
    values:{
        a:0,
        b:1
    }
}

这样其实就能够认为是咱们提到范式化或者说是扁平化了。具体到前端数据范式化以前 咱们来看看数据库的范式吧数据库

具体到前端数据范式化以前 咱们来看看数据库的范式吧

什么是范式:
顾名思义,一个规范模式(虽然有点粗暴,但好像就是这么回事)。
原本想找段定义贴在下面,不过看了看太生硬了,写下我的看法好了。json

第一范式 1NF
表的列具备原子性,不可再分解。
只要是关系型数据库就知足1NFredux

第二范式 2NF
前提是知足1NF,在1NF的基础上。每一行或者实例必须惟一能够被区分,即须要咱们说的主键(key)。后端

第三范式 3NF
知足1NF和2NF,且一个数据库表中不包含已在其余表中包含的非主键字段。
也就是说表中不冗余,能够经过关系从其余表中获取就不要单独存放了,也就是相关信息能够经过外键相关联。 有个图表达的很不错,借来一用:

固然后面还有其余范式这里就先不提了。

总结一下,范式就是为了减小冗余,提升效率
遵循的范式越高,冗余越小,但也要具体分析,不可一味追求符合范式。
有些时候一昧的追求范式减小冗余,反而会下降数据读写的效率,这个时候就要反范式,利用空间来换时间。

redux中的state设计要求

redux针对state的设计也提出了范式化的要求,对于复杂的数据结构,除了数据重复以外,还可能有下面这些问题:

  • 当数据在多处冗余后,须要更新时,很难保证全部的数据都进行更新。
  • 嵌套的数据意味着 reducer 逻辑嵌套更多、复杂度更高。尤为是在打算更新深层嵌套数据时。
  • 不可变的数据在更新时须要状态树的祖先数据进行复制和更新,而且新的对象引用会致使与之 connect 的全部 UI 组件都重复 render。尽管要显示的数据没有发生任何改变,对深层嵌套的数据对象进行更新也会强制彻底无关的 UI 组件重复 render

因此,在 Redux Store 中管理关系数据或嵌套数据的推荐作法是将这一部分视为数据库,而且将数据按范式化存储。
有这么几点概念:

  • 任何类型的数据在 state 中都有本身的 “表”。
  • 任何 “数据表” 应将各个项目存储在对象中,其中每一个项目的 ID 做为 key,项目自己做为 value。
  • 任何对单个项目的引用都应该根据存储项目的 ID 来完成。
  • ID 数组应该用于排序。

具体实践-Normalizr

这里就须要提到Normalizr了,对于复杂数据管理,基本都会提到它。其做用很直白的经过其简介体现出来:Normalizes nested JSON according to a schema。依据模式规范化的处理json。
其用法这里就不介绍了,只提供下转换先后的数据作个对比。有兴趣的你们去官网一看便知。

原始数据:

{
  "id": "123",
  "author": {
    "id": "1",
    "name": "Paul"
  },
  "title": "My awesome blog post",
  "comments": [
    {
      "id": "324",
      "commenter": {
        "id": "2",
        "name": "Nicole"
      }
    }
  ]
}

转换后

{
  result: "123",
  entities: {
    "articles": {
      "123": {
        id: "123",
        author: "1",
        title: "My awesome blog post",
        comments: [ "324" ]
      }
    },
    "users": {
      "1": { "id": "1", "name": "Paul" },
      "2": { "id": "2", "name": "Nicole" }
    },
    "comments": {
      "324": { id: "324", "commenter": "2" }
    }
  }
}

这样的数据就比较符合咱们前面redux设计要求了。

结束语

到这里前端数据的范式化也就介绍的差很少了,一个感悟是js中的数据结构设计未尝不是数据库设计,去遵循相应的范式会让咱们的数据结构更加清晰明了。就算开始没考虑到,随着业务量级的上升本来结构遇到的问题,开发的时候天然也会去往更优雅的方向去靠,这就是进步的过程。
不过仍是那句话,要基于实际状况来看待,不要盲目引入,化简为繁不是一种值得称赞的作法。
通篇文章为我的看法,抛砖引玉有不对的地方欢迎指出

参考文章:

https://blog.csdn.net/qq_35401191/article/details/82760301
https://zhuanlan.zhihu.com/p/36487766
http://cn.redux.js.org/docs/recipes/reducers/NormalizingStateShape.html

相关文章
相关标签/搜索