key+value实现动态字段的存储设计

一般我们在存储例如用户信息的时候,用户信息的各属性是固定的,这时我们可以通过如下方式设计表:
user(user_id, name, age, sex)

但是,如果某天呢,产品说用户信息需要加几个属性:height、weight。

此时,如果表没什么数据当然是想加直接加上就行了,代码中跟着添加几个字段就OK了。但是如果数据量和并发量特别大怎么办?

alter table add column是不行的,因为锁表时间会很长。

这里说一种key+value的存储方式实现方法,此时表设计为:
user(user_id, key, value)

表里数据样式为:

user_idkeyvalue
1name张三
1age50
1sex
1height170
1weight120
2name小胖呆
2age30
2sex

这种将一行存储的数据拆成在一列里面存储的方式就是key+value动态字段存储

key+value存储方式优缺点

优点:
 可以随时动态扩展字段属性

缺点:
1) key值有大量冗余。建议key短一些
2) 行数会增加很多
3)索引设计可能比较麻烦

key+value存储方式使用场景

服务端,wordpress,EAV,配置,统计项、APP或者PC客户端、保存个人信息等等

key+value应用场景之——自定义页面功能设计

在有些系统中,可能会有这样一个需求:用户可以自定义某个页面的表单个数及样式。至于样式的自定义怎么实现,不是这里要说的,这里只说说关于表单个数的自定义实现。

在这种需求里,你不会知道用户到底会定义多个表单,这样你就不能在一张表里固定字段的个数。这时就可以利用key+value方式实现。

我们模拟一个业务场景:系统中有一个作物信息采集页面,每个种植公司可根据自己的需求设置不同的表单;例如公司A希望该页面能收集:作物品种、种植地块、作物高度、有无草害、有无虫害;而公司B则希望收集:作物品种、种植地块、当时田间温度、采集时间。

先设计出如下几张表(只有关键的字段):

模(mu)板表model(id, model_name, company_id)
字段描述分别是:主键、模板名称、公司ID

模板部件表model_parts(id, key_name, label, required, type, model_id)
字段描述分别是:主键、表单name,表单里的label、是否必填、类型(数字或字符串)、模板ID

作物信息采集表crop_info(id, key, value, company_id, model_id)
字段描述分别是:主键、表单name,表单值,公司ID,模板ID

接着给各表添加数据

模板表(model)需要管理员添加数据:

idmodel_namecompany_id
1玉米数据采集模板100
2土豆数据采集模板101

部件表(model_parts):在作物采集页面显示的都是来源于部件表的数据。

idkey_namelabelrequired(1:必填,0:非必填)type(1:数字,2:字符串)model_id
1category作物品种121
2land_name种植地块121
3height作物高度111
4grass有无草害111
5insect有无虫害111
6category作物品种122
7land_name种植地块122
8temperatrue田间温度122
9collect_time采集时间122

作物采集表: crop_info

idkeyvaluecompany_idmodel_id
1category玉米1001
2land_name地块一1001
3height120 cm1001
4grass1001
5insect1001
6category土豆1012
7land_name江家湾地块1012
1temperatrue36.51012
1collect_time2018-10-101012

以上所有遵循正规的表设计,这里只是提供一个思路

作物采集表就完全体现了key+value动态存储的思想。

MySQL动态扩展字段指的是在表中动态地添加或删除列,以适应业务需求的变化。这种需求通常在存储不规则数据或者需要频繁修改表结构的场景下出现。 下面是一种常见的MySQL动态扩展字段设计方案: 1. 创建主表和扩展表:主表中存储常规的数据,扩展表中存储动态扩展的字段。 ``` CREATE TABLE main_table ( id INT PRIMARY KEY, name VARCHAR(50), age INT, gender VARCHAR(10) ); CREATE TABLE extension_table ( id INT PRIMARY KEY, column_name VARCHAR(50), column_value VARCHAR(100) ); ``` 2. 将扩展表中的列转换为行:将扩展表中的每个列转换为行,以便于查询和管理。可以使用MySQL的PIVOT操作或多次JOIN操作来实现。 ``` SELECT id, MAX(CASE column_name WHEN 'address' THEN column_value ELSE NULL END) AS address, MAX(CASE column_name WHEN 'phone' THEN column_value ELSE NULL END) AS phone, MAX(CASE column_name WHEN 'email' THEN column_value ELSE NULL END) AS email FROM extension_table GROUP BY id; ``` 3. 动态添加和删除字段:可以使用ALTER TABLE语句来动态添加和删除扩展表中的字段。 ``` ALTER TABLE extension_table ADD COLUMN column_name VARCHAR(50); ALTER TABLE extension_table DROP COLUMN column_name; ``` 4. 数据访问控制:可以使用MySQL的用户管理功能,限制不同用户对数据的访问权限。 总之,MySQL动态扩展字段设计需要考虑主表和扩展表的关系、扩展字段存储方式、查询方式以及数据访问控制等方面,以便于灵活地适应业务需求的变化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值