EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)

来源:https://www.cnblogs.com/wuhuacong/p/18191039
-Advertisement-
Play Games

一般我們在開發的時候,習慣上使用常規的關係型資料庫來設計資料庫表,對於一些業務表的欄位比較固定的場景,是一種非常不錯的選擇,而且查詢的時候,由於是基於固定的表欄位進行查詢,性能基本上是最優的。不過有一些場景下,業務信息的經常變化,使用常規的關係型資料庫來創建表欄位、刪除欄位的模式,肯定不是合適的處理... ...


一般我們在開發的時候,習慣上使用常規的關係型資料庫來設計資料庫表,對於一些業務表的欄位比較固定的場景,是一種非常不錯的選擇,而且查詢的時候,由於是基於固定的表欄位進行查詢,性能基本上是最優的。不過有一些場景下,業務信息的經常變化,使用常規的關係型資料庫來創建表欄位、刪除欄位的模式,肯定不是合適的處理方案,因此可能會進入JSON數據存儲的方式,而現今很多關係型資料庫也都支持JSON的存儲和子查詢處理,不過JSON的檢索還是比較麻煩,而且對於複雜的子查詢,性能據說也好不到哪裡。而非關係型資料庫的NoSQL資料庫(MongoDB資料庫),它的產生就是為瞭解決大規模數據集合多重數據種類帶來的挑戰。結合關係型資料庫的熟練使用、性能優勢和MongoDB資料庫的彈性化文檔處理特點,我對EAV模型(實體-屬性-值)的設計和低代碼的處理方案提供一個實用的思路供參考。

1、資料庫 EAV 模型設計

如果我們要做一個電商的商品管理,我們先賣一些衣服,需要管理衣服的尺碼、顏色、款式等信息;有一天需要賣電腦了,電腦需要 主板、CPU、顯卡、記憶體、硬碟、散熱 等信息;過幾天又需要賣手機了,手機有 顏色、版本、存儲容量、套餐類型等等信息。資料庫的頻繁更改,可能會導致開發的複雜度增加,說不准要重新處理。

如果我們每次新增商品,需要支持不同的信息的話就不停的加欄位。這樣會導致很多問題:

1、實現成本高,每次可能需要重新修改底層代碼,界面佈局及相關處理等

2、性能越來越差,每次增加的欄位,隨著複雜性越來越大,欄位越來越多,導致性能急劇下降。

3、維護越來越難,沒有好的系統規劃,就如在沙堆上建設豪華城堡,隨著時間的推移,越來越難維護。

還有一種是採用JSON數據存儲方案,對於擴展的數據,可以統一存儲在某個JSON裡面,這樣設計的擴展欄位,可以有效屏蔽一些複雜度,並提高彈性化。如可以把 尺碼、顏色、款色、主板、CPU、顯卡、記憶體等等都放到 JSON 里。

不過這樣JSON數據存儲方案,對於更新和條件查詢來說,性能是比較差的,隨著數據量和複雜度的增加,這種響應效果肯定不如意的,對於大數據的處理,這種處理肯定是災難性的。

EAV(Entity-Attribute-Value)模型是一種靈活的資料庫設計方法,特別適合存儲具有可變屬性的實體。

  • Entity:實體,代表一個業務對象,比如上面的例子里的商品。
  • Attribute:對象的屬性,屬性並不是作為實體單獨的一列來進行存放,而是存儲在一組單獨的資料庫表中。
  • Value:指特定屬性所關聯的值。

在電商商品管理系統中,商品的屬性可能會變化,因此EAV模型是一個合適的選擇。每個實體都有唯一的標識符,每個實體都可以有多個屬性與之關聯,每個屬性都有唯一的標識符,每個屬性都可以具有多個值。

以下是一個簡單的EAV模型設計示例:

實體表(Entity Table):

這裡的實體是指商品。可能這裡用實體類型表述更準確。

屬性表(Attribute Table):

這裡的屬性是指商品的特征,例如顏色、尺寸等。

值表(Value Table):

這裡存儲了實體和屬性的關聯,以及具體的屬性值。

這樣設計的好處在於,你可以靈活地添加新的屬性,而無需修改資料庫結構。然而,EAV模型也有一些缺點,例如查詢可能會更加複雜,因為需要在值表中進行屬性值的連接。

 

2、優化的EAV模型

對於上面屬性值的存儲,統一都採用字元串的方式來存儲,這樣對於類型的處理和空間節約肯定是不好的,因此我們需要進行優化,根據不同的類型存儲在不同的表上。

上面屬性值沒有類型限制,都是 VARCHAR 的,對資料庫不友好,會導致記憶體浪費,而且存取都需要進行數據格式轉換。對存儲為字元串的值創建的索引不允許針對數值型和日期型的搜索範圍優化,這是採用混合數據類型的鍵-值對描述數據的公共問題。

我們對屬性值表基於數據類型進行分割,每個不同的數據類型拆為一個單獨的表,同時通過 屬性表(Attribute) 添加 類型決定去哪裡存取數據。

 我們可以借鑒magento的eav模型,它是EAV設計的最優參考了。Magento 2中的EAV屬性類型有下麵這些表:

  • eav_entity_int
  • eav_entity_varchar
  • eav_entity_text
  • eav_entity_decimal
  • eav_entity_datetime

這5種屬性類型就相當於欄位類型,一般關係型資料庫類型是通用的。

  • int 對應欄位的int類型
  • varchar 對應欄位的varchar類型
  • text 對應欄位的text類型
  • decimal 對應欄位的decimal類型
  • datetime對應欄位的datetime類型

這樣分別不同類型的數據進行不同表的存儲了。

其他的屬性類似的處理即可。

參考下eav的設計圖,瞭解一下各個表之間的關係。

以及magento的eav模型設計圖,複雜的令人抓狂。

3、NoSQL資料庫的登場

使用EAV(Entity-Attribute-Value)模式來存儲完整的數據結構信息以及NoSQL資料庫來存儲完整的記錄是一種靈活的方法,特別適用於需要存儲動態結構數據的場景。

EAV的常規關係型資料庫表存儲常規的設計表,如實體類型、屬性定義、屬性值(多個)表的相關信息,而利用MongoDB資料庫的大數據處理靈活性和高性能的響應,能夠存儲我們實際變化的文檔信息。在檢索的時候,並提供了常規關係型資料庫的聯合查詢、JSON查詢無法得到的靈活性和高性能。好馬配好鞍,雙劍合璧,簡直完美。

在介紹實現我們的EAV模型設計的過程前,我們先來看看實際的界面效果

1)實體類型表和屬性定義處理

 我們新增實體類型的時候,只需要填寫簡單的信息和類名即可,如果對於產品的定義。

 屬性定義,除了指定屬性的一些名稱、排序、預設值、屬性值存儲類型外,還可以設置是否為字典列表、或者從其他類型表中選擇等處理。

 有了欄位的定義,我們就可以在業務列表中顯示相關的欄位,並從MongoDB總檢索指定類型的數據,由於MongoDB本身支持非常好的查詢處理,因此對於查詢來說非常簡單。

如對於產品定義和數據展示來說,我們動態創建的菜單,根據實體類型的ID就可以進行通用的查詢了。如下界面所示。

這個表的數據在MongoDB中存儲的,如下界面所示。

 

 對於有主從表的業務處理,也是同樣的處理方式,除了顯示主表的信息外,還需要展示明細的記錄數據,我們通過整合關係型資料庫的EAV表和MongoDB的文檔記錄顯示,就可以很好的展示相關的數據了。

我們在訂單明細表中選擇表的設置,我們可以再明細表格中動態進行數據的選擇處理, 並可以設置關聯複製的屬性欄位,如下界面所示。

訂單明細表的產品名稱屬性信息定義如下所示。

 

因為訂單明細表中,有時候需要複製來自產品信息的一些欄位,我們在按鈕【設置其他複製欄位】中處理映射關係即可。

這樣就可以自動引入選擇表的屬性值來填充了。 

以上就是針對EAV模型設計,以及引入MongoDB來存儲詳細數據記錄,以便高效的查詢數據和處理動態化欄位內容的需求。

有時間會繼續寫文章介紹詳細的實現過程,以及界面的動態化處理模式。

專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。
  轉載請註明出處:撰寫人:伍華聰  http://www.iqidi.com 
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 有時候,我們需要在網頁判斷用戶是否處與非活躍狀態,如果用戶長時間沒有在頁面上進行任何操作,我們則判定該用戶是非活躍的。 在 javascript 中我們可以通過監聽某些滑鼠或鍵盤相關的事件來判定用戶是否在活躍中。 ...
  • 一、執行上下文 簡單的來說,執行上下文是一種對Javascript代碼執行環境的抽象概念,也就是說只要有Javascript代碼運行,那麼它就一定是運行在執行上下文中 執行上下文的類型分為三種: 全局執行上下文:只有一個,瀏覽器中的全局對象就是 window對象,this 指向這個全局對象 函數執行 ...
  • 最近項目中需要用到js庫來渲染pdf文件,調研後發現無論是reach-pdf.js或者是svelte-pdf.js都是在pdf.js基礎上做了些許精簡,反而功能還不如原始的pdf.js來得全面。但是原始的庫幾乎沒有像樣的代碼示例,而能搜索到的大多數代碼不少都是十幾年前的了,在這個過程中踩了不少坑,做 ...
  • 一、是什麼 webpack proxy,即webpack提供的代理服務 基本行為就是接收客戶端發送的請求後轉發給其他伺服器 其目的是為了便於開發者在開發模式下解決跨域問題(瀏覽器安全策略限制) 想要實現代理首先需要一個中間伺服器,webpack中提供伺服器的工具為webpack-dev-server ...
  • 前言 在家沒事的時候刷抖音玩,抖音首頁的視頻怎麼刷也刷不完,經常不知不覺的一刷就到半夜了 不禁感嘆道 "垃圾抖音,費我時間,毀我青春" 這是我的 模仿抖音 系列文章的第二篇,本文將一步步實現抖音首頁 視頻無限滑動 的效果,乾貨滿滿 第一篇:200行代碼實現類似Swiper.js的輪播組件 第 ...
  • 一、錯誤類型 任何一個框架,對於錯誤的處理都是一種必備的能力 在Vue 中,則是定義了一套對應的錯誤處理規則給到使用者,且在源代碼級別,對部分必要的過程做了一定的錯誤處理。 主要的錯誤來源包括: 後端介面錯誤 代碼中本身邏輯錯誤 二、如何處理 後端介面錯誤 通過axios的interceptor實現 ...
  • 目錄VUE-局部使用快速入門常用指令v-forv-bindv-if & v-showv-onv-modelvue生命周期AxiosVue案例 VUE-局部使用 Vue 是一款用於構建用戶界面的漸進式的JavaScript框架。 (官方:https://cn.vuejs.org/) 快速入門 準備 準 ...
  • 前言 在上一篇 vue3早已具備拋棄虛擬DOM的能力了文章中講了對於動態節點,vue做的優化是將這些動態節點收集起來,然後當響應式變數修改後進行靶向更新。那麼vue對靜態節點有沒有做什麼優化呢?答案是:當然有,對於靜態節點會進行“靜態提升”。這篇文章我們來看看vue是如何進行靜態提升的。 什麼是靜態 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...