sublime text中文乱码mysql字段动态扩展_如何⽤动态字段实现系统的扩展性?设计系统架构时,我们总是希望⼀个架构或者说是模型能⽀持多种业务场景,当然场景是系统范围内的。⽐如说做商品系统,商品有多种属性,不同类型的商品的属性不⼀样,怎么⽤关系型数据库去保存这些不同的属性呢?再⽐如做CMS时,除了基本的背景、位置、类型、状态等属性⼀致外,页⾯不同地⽅需要的数据结构却是不⼀样的。
再⽐如做⼴告时,不同地⽅的⼴告需要⽤不同属性去区别,⽽它们⼜有⼀些共有的属性,⽐如类型,名称。
经过思考和查询,知道有如下⼏种⽅法来存储不同数据。 动态添加属性字段、 JSON 格式保存、 预留字段、 属性字段⾏存储。以⽤java为编程,mysql数据库为例,分别说下这⼏种⽅式如何实现动态字段。
1. 动态添加属性字段。10个微量元素口诀
意思是,在需要添加⼀个属性时。先在数据库的表⾥添加⼀个字段,⽐如给新上的商品有"产地“这个属性,就给product表添加⼀个"产地"字段。那么要⽤这个字段时,还要改相应的java程序。显然这种⽅式不利于灵活扩展,⽽且在⼀张⼤表添加⼀个字段需要较长时间,这也不适合7*24的服务。
2.JSON 格式保存。mysql是什么系统
就是说把需扩展的⼀组字段都到到⼀个字段⾥,各个字段⽤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
createnodedistinct 主表.* from 主表 left join 属性表 on 主表.id=属性表.主表id where
property_name=?
property_value=?。先这样查出主表信息,兼顾了属性表的条件。再根据这个sql查出的主表id去查属性表相应的属性。
当然要组合这两块数据,还得⼀个中间的关联结构,如上⾯的Map>。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。