我有一个当前看起来像这样的数据库表:
PageField
-Id (Int, PK)
-FieldType (String) Can be Text, Decimal, Integer or Bit
-Value (This stores the value regardless of the FieldType, so it is not strongly typed)
我应该删除Value列并将其替换为 4 个单独的列TextValue、DecimalValue、IntegerValue和BitValue吗?
数据类型将设置为相关的。这意味着这 4 列中的每行 3 都是NULL
.
这个问题(以各种形式)经常出现。这种类型的“解决方案”被称为EAV(实体属性值),这不是一个好主意。在此处或此处查看有关它可能导致的问题以及如何正确利用 RDBMS 提供的数据类型的提示(或提示链接)。
不使用正确的数据类型肯定会混淆 查询优化器并降低系统速度。Joe Celko是世界知名的 SQL 专家,他的观点值得关注。
事实上,他使用首字母缩略词“MUCK”(*) 来描述这个系统应该告诉你所有你需要知道的:-)
(*) 大规模统一代码密钥
要向 Vérace (+1) 的正确答案添加一点,您应该更进一步,而不是将不同的类型分成不同的列,您还应该定义您的列是什么并适当地使用它们。这称为设计,它是可理解、可扩展、性能良好的系统的必要步骤。
只是为了达到可以理解的角度,比较一下:
有了这个:
有了这个:
如果您正在尝试创建一个灵活的应用程序,用户可以在其中创建自己的“表单”/“屏幕”/“页面”,我建议您创建不同的“模块”,为模块创建特定有意义的表名,并为模块创建特定有意义的标记列每个字段而不是一个表来存储可以是任何东西的字段。
使用您当前的设计,您将生成一个非常慢的应用程序,并且为报告目的检索数据也将变得乏味。
允许您的用户选择一个“模块”,然后从该模块中选择一组特定字段来生成他们的页面。
您会为了更多的管理工作而牺牲灵活性,但这是值得的。
这取决于你想用“价值”做什么。例如,如果您需要 sum(...),最好有一个小数列并使用“case when fieldtype='N' then sum(cDecimal) When ..”。
在标签 [eav] 上搜索——有很多关于它的弊端的讨论。当您需要对存储在
VARCHAR
.