设计系统架构时,我们总是希望一个架构或者说是模型能支持多种业务场景,当然场景是系统范围内的。比如说做商品系统,商品有多种属性,不同类型的商品的属性不一样,怎么用关系型数据库去保存这些不同的属性呢?再比如做CMS时,除了基本的背景、位置、类型、状态等属性一致外,页面不同地方需要的数据结构却是不一样的。

再比如做广告时,不同地方的广告需要用不同属性去区别,而它们又有一些共有的属性,比如类型,名称。

经过思考和查询,知道有如下几种方法来存储不同数据。 动态添加属性字段、 JSON 格式保存、 预留字段、 属性字段行存储。以用java为编程,mysql数据库为例,分别说下这几种方式如何实现动态字段。

1. 动态添加属性字段。

意思是,在需要添加一个属性时。先在数据库的表里添加一个字段,比如给新上的商品有"产地“这个属性,就给product表添加一个"产地"字段。那么要用这个字段时,还要改相应的java程序。显然这种方式不利于灵活扩展,而且在一张大表添加一个字段需要较长时间,这也不适合7*24的服务。

2.JSON 格式保存。

就是说把需扩展的一组字段都到到一个字段里,各个字段用json的方式组成一个大的字符串。比如:{"clsTypeName":"java.lang.Integer","srcDes":"支持数字或数字区间,如10,2-5","storeCol":"field2","storeName":"ord","viewName":"排名"}。这种方式,添加、修改、删除问题都不大,但查询不方便,比如要查询viewName='排名'的,就要遍历所有数据才行。如果有复杂查询,比如group

by

viewName,这将是个噩梦。所以这种方式只能用于数据量很少的方式,比如就10行数据,且没有复杂查询。曾经我设计了这么一张表,业务上需json中的一个字段为唯一键。那么要实现这个功能,就要添加时遍历所有数据。更不用说后面的查询了,于是我立即弃用了这个设计。

3.预留字段。

就是先给表定义几个扩展字段,还是以商品表为例。给product添加field1,field2,field3三个varchar(200)类型的字段,这样任何数据类型都可以解析为字符串,把编码后的数据存进去就行了。但这还需要对应关系。比如家电类(type=1)的,field1表示颜色,field2表示型号,field3表示功率。而图书类(type=2)的,field1表示出版商,field2开本,field3表示版次。这种设计可以解决一些查询问题,比如我要查询”机械工业出版社"的,那么条件就是type=2

and field1='机械工业出版社'。上面我那个唯一键的需求也可用类似的方法来实现。

它的缺点是字段是公用的,不能顾名思义,得先查对应关系。另外扩展字段的数量无法精确定义,也存在数据量大时添加字段卡顿的风险。因为我刚做了这样的一个应用,再详细说下代码实现。

a.新增。

前台页面输入时并不知道需要录入那几个字段,上面的家电需要field1、field2、field3三个输入,这需要查定义。

不同的类型需要添加的字段名也不一样,比如上面的家电类的,需先有个对应关系,如下:

{"clsTypeName":"java.lang.Integer","srcDes":"RGB值","storeCol":"field1","storeName":"color","viewName":"颜色"}

storeCol代表真实的字段名,而storeName代表逻辑上的字段名。在添加时,如果页面上的input

标签name="真实字段名(field1)",那么在进行唯一值判断时就需要转换。比如要颜色是唯一键,但页面上只有field1,我们并不知道field1代表什么。但有了上面的对应关系,我们就可以写代码了,如果input的name对应的storeName字段值为color,表示要对这个字段(field1)进行查找来实现唯一键的功能。mybatis存储时,最好也只存储上面从定义查出来的的三个字段。这就需要在Product里定义一个Map属性来存放这些扩展属性,以便动态扩展。mybatis的xml可这么写:

b.查询。

我这里的查询只是把数据友好的显示在一个表格中,表格需要表头与内容。因为这里涉及到一个动态字段的问题,我们并不知道显示的表格有多少个动态字段。所以需要先从定义表查出有多少个字段,还要根据列名合并。比如家电类产品有颜色、型号、功率三个属性,而个人护理/化妆类作品有颜色、厂家两个属性,那么我们展示的属性有颜色、型号、功率、厂家四个属性,颜色属性就合并了。所以要先从定义表里取出这么个结构Map>。这样从这结构里取出所有不同的显示字段名,每一行得到类型ID后,再根据当前列名取出存储字段名,再用当前行对象.存储字段名(obj.field1)就可取出真实值了。

4.属性字段行存储

这种方式与3有很一些类似的解决办法,最大的好处是扩展字段时不需要修改表结构,而不好的主要是查询变困难了。新建一个有如下图3列的表,主键(product_id),属性名(property_name),属性值(property_value)

a.新增与删除。

与3一样需要一个定义属性的地方,但不需要添加field1,field2这样不知什么意思的字段名。直接把上面的storeName的值做为property_name的值。如上面的color。这样再扩展字段时,就添加一行就行。这样输入时的input为storeName(如color)。insert时需插入两张表,先插入主表得到id,再插属性表,属性表的插入行数不能确定,可由输入的属性数来确定。删除时也要删除两张表。

b.查询。

我目前是这样的,select

distinct 主表.* from 主表 left join 属性表 on 主表.id=属性表.主表id where

property_name=?

property_value=?。先这样查出主表信息,兼顾了属性表的条件。再根据这个sql查出的主表id去查属性表相应的属性。

当然要组合这两块数据,还得一个中间的关联结构,如上面的Map>。

mysql字段动态扩展_如何用动态字段实现系统的扩展性?相关推荐

  1. mysql分表动态扩展_小星星 的动态 - SegmentFault 思否

    DolphinDB支持动态加载外部插件,以扩展系统功能.插件用C++编写,需要编译成".so"或".dll"共享库文件.本文着重介绍开发插件的方法和注意事项,并 ...

  2. mysql动态扩展_动态可扩展查询MYSQL5.7JSON+虚拟列+Mybatis

    背景:现有业务扩展字段,都存在feature字段,存在语义不清晰以及,难以利用索引查询问题 Mysql 5.7后推出利器,JSON+虚拟列,即实现了业务语义统一,也支持索引查询加速 一.简单描述 My ...

  3. mysql函数 动态语句_自定义函数动态执行SQL语句

    Oracle 动态SQL有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者. DDL 和 DML Sql代码 收藏代码 /*** DDL ***/ begin EX ...

  4. java动态扩展_java栈内存动态扩展要怎么理解?要如何实现?

    小伙伴们知道如何在java栈中内存动态扩展吗?这是虚拟机中的一个概念,下面让我们一起来看看该如何实现吧. 一.内存概念 在java中,我们一般会简单把java内存区域划为两种:堆内存与栈内存.其实这种 ...

  5. 利用代码分别实现jdk动态代理和cglib动态代理_面试之动态代理

    大家好!我是CSRobot,从今天开始,我将会发布一些技术文章,内容就是结合春招以来的面试所遇到的问题进行分享,首先会对知识点进行一个探讨和整理,在最后会给出一些面试题并作出解答,希望可以帮助到大家! ...

  6. mysql数据库搭建动态网站_数据库和动态网页怎么建立联系

    展开全部 ASP常用数据库连接及操作的方32313133353236313431303231363533e78988e69d8331333236396366法和技巧 1.ASP连接Access数据库 ...

  7. python 网页樱花动态图_如何用Python实现动态图?

    GIF(Graphics Interchange Format,图形交换格式)是一种位图图像格式, GIF格式的图像文件具有如下特点: (1)GIF格式图像文件的扩展名是".gif" ...

  8. mysqli 语句和mysql语句一样吗_如何为动态sql语句准备mysqli语句

    我想为动态sql语句准备一个语句,这个语句取决于用户的决定.所以我不知道它会是什么样子.我不能事先为它做一个模板.例如: mysqli_report(MYSQLI_REPORT_ERROR | MYS ...

  9. mysql 字段集合运算_如何用SQL进行集合运算

    如何用SQL进行集合运算 发布时间:2020-07-15 14:31:43 来源:亿速云 阅读:117 作者:Leah 今天就跟大家聊聊有关如何用SQL进行集合运算 ,可能很多人都不太了解,为了让大家 ...

  10. python代码画动态烟花_如何用python画烟花

    用python画烟花的方法:首先创建一个所有粒子同时扩大的二维列表:然后实现粒子范围扩大,以自由落体坠落:接着移除超过最高时长的粒子:最后循环调用保持不停. 用python画烟花的方法:# -*- c ...

最新文章

  1. 将字符串型转换为整形
  2. 在MyEclipse中添加 XML Catalog (xwork-validator dtd )
  3. 面对对象编程(OOP, Object Oriented Programming)及其三个基本特性
  4. three.js(五) 地形纹理混合
  5. 02-02 Python 读写文件 open|os|sys
  6. python文本编辑器下载_海龟编辑器官方下载|海龟编辑器(Python编辑器)下载 v1.3.4 官方版 - 绿点软件站...
  7. c++ 中 try catch throw异常
  8. 北航的计算机与技术专业如何,计算机科学与技术考研北航的这个专业怎么样
  9. abaqus算出来的转角单位是什么_abaqus单位等等
  10. catia三边倒角_CATIA课时:操作工具栏创建倒角倒圆角视频教程_翼狐网
  11. ubuntu20.4 微信,qq ,等安装安装教程
  12. android linearlayout 自动滚动,Linearlayout scrollbars=“vertical”并没有用,Linearlayout滚动的解决办法...
  13. Cheat Engine(CE)-----下载安装及入门
  14. c语言入门自学mobi,算法精解:C语言描述[AZW3][EPUB][MOBI][23.00MB]
  15. linux c语言乘法口诀表好记方法,乘法口诀表好记方法
  16. 快速打造微信小程序(超详细)
  17. 华为服务器RH2288 V3怎样配置RAID
  18. 全国名医院排行榜(按专科俳名)
  19. 什么是BQB认证?BQB认证蓝牙模块
  20. Oracle 18c:拉里·埃里森亲自支招,数据库自动化之后,DBA何去何从?

热门文章

  1. 如何安全地终止线程interrupt()、isInterrupted()、interrupted()的区别与使用
  2. 简单了解一下如何使用Spring框架里JDBC和事务
  3. Oracle相同的一个SQL执行计划截然不同的解决方法
  4. Spring Data JPA持久层中的一对一和一对多
  5. Redis 对象系统
  6. 网站速度优化模块HttpCompressionModule
  7. 获取单个数据库的邮箱数量
  8. python 穷举法 算24点(史上最简短代码)
  9. kafka 安装步骤
  10. php 打印debug日志