前端數據範式化

前言

現代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

相關文章
相關標籤/搜索