但以下关系存在时,可能会将数据设置成为EAV模式,比如一个问题(Issue),可能有继承它的bug和特性(FeatureRequest),他们的关系如下,引用AntiPatterns

针对上面的关系,如果考虑表格的列可能扩展的情况,设计成EVA(Entity-Atrribute-Value)如下:

CREATE TABLE Issues (issue_id int PRIMARY KEY
);
INSERT INTO Issues (issue_id) VALUES (1234);
CREATE TABLE IssueAttributes
(
issue_id BIGINT NOT NULL,
attr_name VARCHAR(100) NOT NULL,
attr_value VARCHAR(100),
);

通过IssueAttributes表,描述和报告日期通过attribute-value对的方式存储起来,如下:

INSERT INTO IssueAttributes (issue_id, attr_name, attr_value)
VALUES
(1234, 'product', '1'),
(1234, 'date_reported', '2009-06-01'),
(1234, 'status', 'NEW'),
(1234, 'description', 'Saving does not work'),
(1234, 'reported_by', 'Bill'),
(1234, 'version_affected', '1.0'),
(1234, 'severity', 'loss of functionality'),
(1234, 'priority', 'high');

上面的这种设计,优点在于,如果我想增加一个版本的列,可以直接插入一条记录即可,不需要增加一列。但是EAV模式,存在如下一些缺点。

1.不能精确定义数据类型,比如date_reported,报告日期,由于各个国家和地区使用日期格式不尽相同,有些是2020-02-02,有些是2/6/2020等等,甚至有些格式无法转成日期。这样显示和统计都会出错,比如,如下SQL也能插入成功

INSERT INTO IssueAttributes (issue_id, attr_name, attr_value)
VALUES
(1234, 'date_reported', 'haha'),

2.不能定义约束,使用EVA不能定义外键约束;

3.EAV模式中的attribute名称可能不能统一,比如有些插入的是'date_reported',而有些是'report_date',这样无法使用SQL查询;

3.重构查询结果问题

当我们使用 SELECT * FROM IssueAttributes WHERE issue_id =1234;这样语句查询出结果以后,出现了多行,其实我们期望的结果是一行,然后把其他行转化到列上去,尽管有些SQL已经支持了行转列了,但是这样的SQL抬复杂,在不考虑行转列的情况下,需要如下写SQL才可以达到一行,查询多少列就需要关联自身表多少次,降低了查询效率。

SELECT i.issue_id,
i1.attr_value AS "date_reported",
i2.attr_value AS "status",
i3.attr_value AS "priority",
i4.attr_value AS "description"
FROM Issues AS i
LEFT OUTER JOIN IssueAttributes AS i1
ON i.issue_id = i1.issue_id AND i1.attr_name = 'date_reported'
LEFT OUTER JOIN IssueAttributes AS i2
ON i.issue_id = i2.issue_id AND i2.attr_name = 'status'
LEFT OUTER JOIN IssueAttributes AS i3
ON i.issue_id = i3.issue_id AND i3.attr_name = 'priority'
LEFT OUTER JOIN IssueAttributes AS i4
ON i.issue_id = i4.issue_id AND i4.attr_name = 'description'
WHERE i.issue_id = 1234;

针对以上这些问题,一般设计成EAV模式是想要数据库更加灵活,但是这种模式更使用NoSQL数据库,比如使用MongoDB,下一篇文章,我们将介绍针对这种如何设计关系型的解决方案。

SQL反模式:实体-属性-值(EAV)问题(一)相关推荐

  1. PHP设计模式之实体属性值模式(EAV 模式)代码实例大全(35)

    实体属性值(Entity--attribute--value EAV)模式,可以方便 PHP 实现 EAV 模型. 目的 实体属性值模型(Entity-attribute-value EAV)是一种用 ...

  2. java eav模式_实体属性值模式(EAV 模式)

    实体属性值(Entity--attribute--value EAV)模式,可以方便 PHP 实现 EAV 模型. 4.4.1. 目的 实体属性值模型(Entity-attribute-value E ...

  3. Java比较两个实体属性值是否相同,将不同的属性输出

    /*** 比较两个实体属性值,返回一个map以有差异的属性名为key,value为一个Map分别存oldObject,newObject此属性名的值* @param oldObject 进行属性比较的 ...

  4. SQL反模式笔记7——多列属性

    目标:存储多值属性 反模式:创建多个列.比如产品主图,开始需求是,每个产品都是3张图,但随着时间的推移,可能就不止3张了. 1.查询:多个列的话,查询时可能不得不用IN,或者多个OR 2.添加.删除. ...

  5. SQL反模式笔记17——用一条sql解决复杂问题

    目标:检查sql查询次数 反模式:试图用一条sql解决复杂问题 结果是:性能很低,而且往往得到了一个笛卡尔积. 解决方案:分而治之 用多个sql得到数据,再进行整合.或者union多个sql的结果. ...

  6. 【java】List 根据实体属性值搜索

    List 根据实体属性搜索 工具类如下所示,主要使用了泛型,反射 入参: list,待查找的 list field: 要根据 list 中的哪个属性来查找 ,如上面的 TestModel 中的 nam ...

  7. SQL反模式:实体-属性-值(EAV)问题(二)

    在上一篇文章中,介绍了EAV模式存在的问题,文章链接如下: https://blog.csdn.net/dh858115/article/details/104203110 那么针对EAV的问题有什么 ...

  8. mysql 说说反模式设计_sql反模式分析1

    第二章:乱穿马路 2.1 目标:存储多值属性 2.2 反模式:格式化的逗号分隔列表   模糊匹配无法使用索引,影响性能:多表关联麻烦,却极大影响性能:执行聚合查询不方便开发和调试:更新某个字段值必须执 ...

  9. Java反射设置list的属性值_利用java反射比较两个实体有哪些属性值不一样

    分享一个利用反射实现比较两个实体属性值的方法: package net.zwq1105.test; import java.beans.Introspector; import java.beans. ...

最新文章

  1. 【51nod】1239 欧拉函数之和 杜教筛
  2. GC之7大垃圾收集器详解(上)
  3. 电子科技大学计算机网络技术专业,计算机专业前景如何?最强十大高校有哪些?电子科大排名多少?...
  4. 大数据之HDFS应用开发(java API)
  5. 哈工大LTP本地安装及python调用
  6. 二叉查找(排序)树/二叉树----建树,遍历
  7. 开源操作系统年度技术会议图文直播
  8. 数据可视化(5)--jqplot经典实例
  9. 低电阻、高散热、节省空间 工业设备就需要这样的小型DCDC转换器
  10. 2021年全新Java学习路线图,对标阿里P7技术栈
  11. 错误请联系管理员文件 index.php,GS登录报错,提示【访问权限失败,请联系管理员处理】...
  12. 前端白屏问题_H5白屏问题
  13. 知网查重提交论文显示服务器错误,知网查重时显示检测失败是什么原因?
  14. 2020年起重机械指挥模拟试题及起重机械指挥模拟考试题
  15. 杂篇-01-Unity中创建Mesh时遇到的问题
  16. 1024 科学计数法 (20 分) 完全解析(C++详细思路)
  17. Python读取Excel日期列读出来是数字的处理
  18. for(Map.EntryString, String entry:params.entrySet())
  19. 什么是AAC音频格式 AAC-LC 和 AAC-HE的区别是什么
  20. java 重新安装_Java卸载后无法重新安装 提示已安装过

热门文章

  1. POSCMS 后台自定义链接友情链接增加搜索功能
  2. AE动画怎么导出?4种常见导出方式汇总
  3. 160413、生成随机校验码
  4. 在Godot中制作杀戮尖塔的箭头
  5. 佳文分享:CAP定理
  6. 深度链接、延迟深度链接、App Links以及关于LinkedME实现深度链接的原理解析
  7. 徐州php溪谷_ThinkPHP溪谷H5游戏平台系统V3.0完整版源码
  8. 线程控制-客户端获取信息无反应
  9. 如何理解数学公式中出现的极大极小minmax含义
  10. android backtrace,高通android q 通过backtrace使用addr2ine工具定位crash问题记录