我正在研究的这个应用需要存储一些关于实体的元数据字段。问题是我们已经可以预见到这些领域将来会发生很大的变化。现在,每个实体的属性都被转换为实体表中的一列,但是稍后改变表列将是昂贵且容易出错的吗?
我应该选择这样的(键值存储)吗?
MetaDataField
-----
metaDataFieldID (PK), name
FieldValue
----------
EntityID (PK, FK), metaDataFieldID (PK, FK), value [varchar(255)]
P.S。我还想过在SQL Server 05+上使用XML。在与一些人交谈之后,似乎它不是一个可行的解决方案,因为它对于为报告目的而进行某些查询来说太慢了。
答案 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数据库上的查询,约束和约束强制很可能比“常规”数据库结构更改成本高出数千倍。