我分配了一项任务来创建(相对)简单的报告系统。在这些系统中,用户将看到报表的表格结果。一个表有一些字段,每个字段在每条记录中向用户提供部分信息。然而,我的问题是 developer 不会声明每个报告字段。它必须由系统的用户声明。所以我的报告表是动态的。
我在 ' Data Driven Custom View Engine in ASP.NET MVC 中看到了示例' 用于使用 Asp.net MVC Framework 创建动态表单,但我不知道这是否适合我的系统。
更新1:
目前我以以下实体关系图结束:
在上图中,我将报告的每条记录存储在 Report
表中。我还将报告类型存储在 ReportType
中。对于将在报告记录中使用的每个字段,我将使用 ReportFieldValue
。字段类型将存储在 ReportField
中。
所以如果我想先向我的数据库添加一条记录,我会在 Report
表中添加一行。然后对于每个添加的记录字段,我将在 ReportFieldValue
表中添加一行。
但是,您可能会注意到,在这些方法中,我必须将每个字段值存储在 char(255) 中。问题在于不应存储为字符串的字段类型(如 datetime
)。这种类型的系统是否有任何设计模式或架构?
最佳答案
通过将 VALUE
替换为 NUMBER_VALUE
、DATE_VALUE
、STRING_VALUE
,避免使用字符串类型的数据。这三种类型在大多数情况下都足够好。
如果需要,您可以稍后添加 XMLTYPE 和其他花哨的列。对于 Oracle,请使用 VARCHAR2 而不是 CHAR 以节省空间。
始终尝试将值存储为正确的类型。原生数据类型更快、更小、更易于使用且更安全。
Oracle 有一个通用数据类型系统(ANYTYPE、ANYDATA 和 ANYDATASET),但这些类型很难使用,在大多数情况下应该避免使用。
架构师通常认为对所有数据使用单个字段会使事情变得更容易。它使生成数据模型的漂亮图片变得更容易,但它使一切 否则更难。考虑以下问题:
- 在不知道数据类型的情况下,您无法对数据做任何有趣的事情。即使要显示数据,了解类型以证明文本的合理性也很有用。在所有的 99.9% 用例 3 列中的哪一列是相关的,对用户来说是显而易见的。
针对字符串类型的数据开发类型安全的查询是很痛苦的。例如,假设您要查找出生于这个千年的人的“出生日期”:
select * from ReportFieldValue join ReportField on ReportFieldValue.ReportFieldid = ReportField.id where ReportField.name = 'Date of Birth' and to_date(value, 'YYYY-MM-DD') > date '2000-01-01'
你能发现错误吗?上述查询很危险,即使您以正确的格式存储日期,也很少有开发人员知道如何正确修复它。 Oracle 的优化使得强制执行特定的操作顺序变得困难。为了安全起见,您需要这样的查询:
select * from ( select ReportFieldValue.*, ReportField.* --ROWNUM ensures type safe by preventing view merging and predicate pushing. ,rownum from ReportFieldValue join ReportField on ReportFieldValue.ReportFieldid = ReportField.id where ReportField.name = 'Date of Birth' ) where to_date(value, 'YYYY-MM-DD') > date '2000-01-01';
您不想告诉每个开发人员都以这种方式编写查询。
关于mysql - 关系数据库中自定义字段的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31721343/