数据库设计 – 如何构建您的实体模型来存储具有不同数据类型的任
我会继续遇到这样的情况:使用每行键/值模型而不是刚性列/字段模型将一组任意数据存储在表中将是有用的.问题是,我想使用正确的数据类型存储值,而不是将所有内容转换为字符串.这意味着我必须选择具有多个可空列的单个表,每个数据类型一个,或一组值表,每个数据类型一个.我也不确定是否应该使用完整的第三个正常表单,并将键分离成一个单独的表,通过值表引用它们,或者如果最好保持简单的方法并存储值表中的字符串键并接受字符串的重复.
旧/坏: 该解决方案使得添加附加值在流体环境中是一个痛苦,因为表需要定期修改. MyTable ============================ ID Key1 Key2 Key3 int int string date ---------------------------- 1 Value1 Value2 Value3 2 Value4 Value5 Value6 单表解决方案 该解决方案允许通过单个表进行简化.查询代码仍然需要检查空值来确定该字段正在存储的数据类型.也可能需要检查约束来确保只有一个值字段包含非空数据. DataValues ============================================================= ID RecordID Key IntValue StringValue DateValue int int string int string date ------------------------------------------------------------- 1 1 Key1 Value1 NULL NULL 2 1 Key2 NULL Value2 NULL 3 1 Key3 NULL NULL Value3 4 2 Key1 Value4 NULL NULL 5 2 Key2 NULL Value5 NULL 6 2 Key3 NULL NULL Value6 多表解决方案 该解决方案允许更简洁地使用每个表,尽管代码需要事先知道数据类型,因为它需要为每个数据类型查询不同的表.索引可能更简单和更有效率,因为有更少的列需要索引. IntegerValues =============================== ID RecordID Key Value int int string int ------------------------------- 1 1 Key1 Value1 2 2 Key1 Value4 StringValues =============================== ID RecordID Key Value int int string string ------------------------------- 1 1 Key2 Value2 2 2 Key2 Value5 DateValues =============================== ID RecordID Key Value int int string date ------------------------------- 1 1 Key3 Value3 2 2 Key3 Value6 你如何处理这个问题?哪个解决方案更好? 此外,如果密钥列分隔成一个单独的表,并通过外键引用,或者是否应该保留在值表中,如果由于某些原因导致密钥名称更改,批量更新? 解决方法首先,关系数据库不是为了存储任意数据而设计的.关系模型的基本原理在于获取有关存储数据性质的规范.其次,您建议的是实体属性值(EAV)的变体. EAV的问题来自于数据完整性,报告,性能和维护.他们有他们的地位,但它们类似于药物:在有限的数量和狭窄的情况下使用它们可以是有益的;太多会杀了你 针对EAV撰写查询是一种承担.因此,如果要使用EAV,我看到它们的唯一情况是成功的是限制其使用,以便不允许任何人编写用于特定属性过滤的查询.也就是说,没有人会允许写一个类似于AttributeName =’Foo’的查询.这意味着您永远不能过滤,排序,计算,也不能将特定属性放在报表上的特定位置. EAV数据只是一袋分类数据,可以在报告上大量排出,但就是这样.我甚至看到人们将EAVs实现为Xml blob. 现在,如果您使用EAV,因为它只是一个数据块,我将使用单表方法.单表方法的一个重要优点是您可以添加一个检查约束,确保您在IntValue,StringValue或DateValue列中只有一个值.空值不会花费你太多,如果这只是数据,那么它的性能就不会有什么不同.此外,它将使您的查询更简单,您可以使用简单的case语句返回String,Integer或DateValue. 我可以看到多表方法的许多问题,其中最重要的是没有什么可以阻止相同的属性拥有多种类型的值(例如,IntegerValues中的行和StringValues中的一行).另外,要获取数据,您将始终使用三个左连接,这将使您的查询更麻烦地编写. EAV的成本是纪律和警惕.在任何情况下,您的开发团队都必须遵守纪律,从不针对特定属性编写报告或查询.开发人员将从管理层获得很大的压力,“只是一次”,写出一些特定属性的过滤器.一旦你走下黑暗的道路,永远都会主宰你的发展和维护. EAV必须保持一大堆数据,没有更多.如果您不能在开发团队中保持这种纪律,那么我不会实施EAV.为了避免维护噩梦,我需要任何新的列的规范.一旦用户确实要过滤,计算或将属性放在报表上的特殊位置,该属性必须成为第一类列.如果您能够保持使用纪律,EAV可以很好地让用户存储他们想要的任何信息,并推迟您需要获取数据元素的规范的时间,直到用户以前面提到的方式使用该属性. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- SQLSERVER查询单个数据表所有字段名组合成的字符串脚本
- sql – 别名FOR XML PATH结果
- sqlserver2008新增只有查询查询权限的账号
- 在内存数据库中配置特定的测试目的在Spring
- sql-server-2008 – 当主体服务器物理上脱机时,c#中的数据库
- sqlserver数据导入mysql八: 把sqlserver中的存储过程注释后
- SQLServer之创建INSTEAD OF INSERT,UPDATE,DELETE触发器
- ssms – SQL Management Studio 2012是否可用,没有引擎本身
- sql server 编译与重编译详解
- sql boolean 0/1表示true或False