【问题标题】:schema for storing different varchar fields over time?随着时间的推移存储不同 varchar 字段的模式?
【发布时间】:2011-02-19 16:49:49
【问题描述】:

我正在开发的这个应用程序需要存储一些关于实体的元数据字段。问题是我们已经可以预见这些领域在未来会发生很大的变化。现在每个实体的属性都被转换为实体表中的一列,但是以后更改表列将是昂贵且容易出错的,对吧?

我应该选择这样的东西(键值存储)吗?

MetaDataField
-----
metaDataFieldID (PK), name

FieldValue
----------
EntityID (PK, FK), metaDataFieldID (PK, FK), value [varchar(255)]

附言我还想过在 SQL Server 05+ 上使用 XML。在与一些人交谈后,这似乎不是一个可行的解决方案,因为它对于为报告目的进行某些查询会太慢。

【问题讨论】:

    标签: sql-server sql-server-2005 database-design schema


    【解决方案1】:

    “以后更改表列会很昂贵且容易出错,对吧?”

    正如您所命名的,“表列”恰好具有两个属性:名称和数据类型。因此,“更改表列”只能指两件事:更改名称或更改数据类型。

    想要更改名称确实是一项成本高昂且容易出错的操作,但幸运的是,不应该是真正的业务需要。如果某个已建立的栏目看起来有些不合适,事后考虑,并且“它可能被赋予了更好的名称”,那么 企业 仍然不会因此而蒙受损失!还是用旧名字吧,即使事后考虑,它也选得不好。

    想要更改数据类型确实是一项代价高昂的操作,容易破坏正常运行的业务操作,但幸运的是很少有用户过来告诉你“嘿,我知道我告诉过你这个属性必须是一个日期,但你猜怎么着,我错了,它必须是一个浮点数。”。而其他性质相同但更可能发生的变化(例如从shortint到integer左右),可以通过在定义数据库时谨慎来避免。

    其他类型的数据库更改(例如添加新列)通常没有那么危险和/或破坏性。

    因此,不要让自己被那些含糊的口号短语(例如“更改数据库既昂贵又危险”)吓到。他们通常来自对数据库管理知之甚少的无知者,无论如何都无法参与我们专业的特定领域。

    在 EAV 数据库上维护查询、约束和强制执行很可能比“常规”数据库结构更改的成本高出数千倍。

    【讨论】:

      【解决方案2】:

      还需要考虑一种模式——称为观察模式。 查看类似的问题/答案:onetwothree

      Martin Fowler 的Analysis Patterns一书中描述了该模式,本质上它是一个OO模式,但也可以在 DB 模式中完成。

      【讨论】:

        【解决方案3】:

        您是对的,您不想在出现新参数时更改数据架构!

        我见过两种方法来做这样的事情。一,只有一个“元”文本字段,并格式化值以定义参数和值。 Joomla!例如,这样做是为了跟踪自定义文章属性。它看起来像这样:

        ProductTable
             id   name     meta
            --------------------------------------------------------------------------
             1    prod-a   title:'a product title',desc:'a short description'
             2    prod-b   title:'second product',desc:'n/a'
             3    prod-c   title:'3rd product',desc:'please choose sm med or large'
        

        另一种处理方式是使用额外的表格,如下所示:

        ProductTable
             product_id     name   
            -----------------------
             1              prod-a 
             2              prod-b 
             3              prod-c 
        
        MetaParametersTable
             meta_id     name
            --------------------
             1           title
             2           desc
        
        ProductMetaMapping
             product_id     meta_id     value 
            -------------------------------------
             1              1           a product title
             1              2           a short description
             2              1           second product
             2              2           n/a
             3              1           3rd product
             3              2           please choose sm med or large
        

        在这种情况下,查询将需要连接表,但您可以更好地优化表,可以查询独立元而不返回所有参数等。

        在它们之间进行选择将取决于复杂性、数据行是否需要具有不同的元数据以及如何使用数据。

        【讨论】:

          【解决方案4】:

          XML 速度仅取决于进入 xml 列的数据大小。我们有一个将数据填充到 xml 列中并处理数据的项目。它非常快.. 直到你达到 64kb 左右。 63KB 和更少的数据需要几毫秒才能将数据取出或插入。 64KB,操作跳到整整一分钟。去图吧。

          除此之外,我们遇到的主要问题是复杂性。在 sql server 中处理 xml 数据并不适合胆小的人。

          无论如何,最好的办法是拥有一个与相关实体相关联的名称/值对表。然后很容易支持具有不同属性的实体或动态添加/删除属性。这也有它的警告。例如,如果你有 10 个以上的属性,那么在代码中进行数据透视会快得多。

          【讨论】:

            【解决方案5】:

            键值表是个好主意,它的工作速度比 SQL Server 2005 XML 索引快得多。我在一个项目中使用 XML 启动了相同类型的解决方案,并且不得不将其更改为索引键值表以获得性能。我认为 SQL Server 2008 XML 索引更快,但还没有尝试过。

            【讨论】:

            • 哦不知道它叫键值表。谢谢!
            猜你喜欢
            • 2016-10-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-25
            • 2012-04-09
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多