mysql - 关系数据库中自定义字段的设计模式

标签 mysql sql-server asp.net-mvc oracle database-design

我分配了一项任务来创建(相对)简单的报告系统。在这些系统中,用户将看到报表的表格结果。一个表有一些字段,每个字段在每条记录中向用户提供部分信息。然而,我的问题是 developer 不会声明每个报告字段。它必须由系统的用户声明。所以我的报告表是动态的。

我在 ' Data Driven Custom View Engine in ASP.NET MVC 中看到了示例' 用于使用 Asp.net MVC Framework 创建动态表单,但我不知道这是否适合我的系统。

更新1:

目前我以以下实体关系图结束:

enter image description here

在上图中,我将报告的每条记录存储在 Report 表中。我还将报告类型存储在 ReportType 中。对于将在报告记录中使用的每个字段,我将使用 ReportFieldValue。字段类型将存储在 ReportField 中。

所以如果我想先向我的数据库添加一条记录,我会在 Report 表中添加一行。然后对于每个添加的记录字段,我将在 ReportFieldValue 表中添加一行。

但是,您可能会注意到,在这些方法中,我必须将每个字段值存储在 char(255) 中。问题在于不应存储为字符串的字段类型(如 datetime)。这种类型的系统是否有任何设计模式或架构?

最佳答案

通过将 VALUE 替换为 NUMBER_VALUEDATE_VALUESTRING_VALUE,避免使用字符串类型的数据。这三种类型在大多数情况下都足够好。 如果需要,您可以稍后添加 XMLTYPE 和其他花哨的列。对于 Oracle,请使用 VARCHAR2 而不是 CHAR 以节省空间。

始终尝试将值存储为正确的类型。原生数据类型更快、更小、更易于使用且更安全。

Oracle 有一个通用数据类型系统(ANYTYPE、ANYDATA 和 ANYDATASET),但这些类型很难使用,在大多数情况下应该避免使用。

架构师通常认为对所有数据使用单个字段会使事情变得更容易。它使生成数据模型的漂亮图片变得更容易,但它使一切 否则更难。考虑以下问题:

  1. 在不知道数据类型的情况下,您无法对数据做任何有趣的事情。即使要显示数据,了解类型以证明文本的合理性也很有用。在所有的 99.9% 用例 3 列中的哪一列是相关的,对用户来说是显而易见的。
  2. 针对字符串类型的数据开发类型安全的查询是很痛苦的。例如,假设您要查找出生于这个千年的人的“出生日期”:

    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/

相关文章:

mysql - 使用sql在具有不同模式的数据库表之间复制数据

php - Laravel 5 中的未定义属性

c# - 我该如何解决无法隐式将 Generic.List< > 转换为 Generic.List< >

asp.net - 允许在 ASP.NET MVC 表单上使用多个按钮的最佳方法是什么?

asp.net-mvc - 检测页面是否从 RedirectToAction() 方法重定向

python - apscheduler 在查询期间丢失与 MySQL 服务器的连接

php - 在 PHP 中使用 if/else 检查 SQL 查询

sql - 检查 SQL Server 中的 View

mysql - talend 的 utf8mb4 设置 - 不工作

sql-server - 在 SQL Server 中,如何像在 Postgres 中那样将自动增量字段的下一个值设置为任意值?