用于存储不同varchar字段的模式?

时间:2010-05-14 19:59:52

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

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

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

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

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

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

5 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

XML速度仅取决于进入xml列的数据大小。我们有一个项目将数据填入xml列并从中处理数据。它非常快......直到你达到64kb左右。 63KB或更少花费毫秒来获取数据或插入数据。 64KB并且操作跳了一整分钟。去图。

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

无论如何,您最好的选择是将一个名称/值对的表绑定到相关实体。然后,很容易支持具有不同属性的实体或动态添加/删除属性。这也有它的警告。例如,如果您有超过10个属性,那么在代码中进行枢轴转移会快得多。

答案 2 :(得分:1)

你是对的,你不想在新参数出现时改变你的数据模式!

我已经看过两种做这样事的方法。一,只需要一个“元”文本字段,并格式化该值以定义参数和值。的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

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

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

答案 3 :(得分:0)

还有一种模式需要考虑 - 称为观察模式。 请参阅类似的问题/答案: one two three

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

答案 4 :(得分:0)

“稍后改变表格列将是昂贵且容易出错的吗?”

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

想要更改名称确实是一项代价高昂且容易出错的操作,但幸运的是永远不应该是真正的业务需求。如果某个已建立的专栏似乎有些不合适,事后补充,并且“它可能已被赋予更好的名称”,那么业务仍然不会因此而遭受损失!只要坚持使用旧名称,即使事后考虑,也很难选择。

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

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

所以不要让自己被那些模糊的口号短语吓到,比如“改变数据库既昂贵又危险”。他们通常来自对数据库管理知之甚少的无知者,无论如何都要参与我们职业的这个特定领域。

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