Database design p在客户和CustomerCustomField表之间(分别)。关于定义与自定义属性的关系的第二个问题需要考虑。首先想到的是添加一个DataSource字段,该字段将包含属性值绑定到的表。因此,基本上,您的CustomerCustomField看起来像: 客户ID 财产 价值观 ValueDataSource(可为空)
这应该允许您绑定到特定的数据结构,或者只允许您指定未绑定的值。您可以进一步规范化这个模型,但是类似的东西可以工作,并且应该很容易在代码中处理 如果这些“额外”字段是偶然出现的,并且不想对它们进行搜索,我通常会选择选项2(但更喜欢JSON而不是XML)。如果要在自定义字段上进行搜索,选项3并不难,通常SQL优化器可以从中获得合理的性能。选项4或5将是我的选择。如果您的数据很重要,我不会用选项3丢弃您的类型信息。(您可以尝试自己实现完整类型检查,但这是一项相当大的工作,数据库引擎已经为您完成了这项工作。) 一些想法:Database design p在客户和CustomerCustomField表之间(分别)。关于定义与自定义属性的关系的第二个问题需要考虑。首先想到的是添加一个DataSource字段,该字段将包含属性值绑定到的表。因此,基本上,您的CustomerCustomField看起来像: 客户ID 财产 价值观 ValueDataSource(可为空),database-design,data-modeling,Database Design,Data Modeling,这应该允许您绑定到特定的数据结构,或者只允许您指定未绑定的值。您可以进一步规范化这个模型,但是类似的东西可以工作,并且应该很容易在代码中处理 如果这些“额外”字段是偶然出现的,并且不想对它们进行搜索,我通常会选择选项2(但更喜欢JSON而不是XML)。如果要在自定义字段上进行搜索,选项3并不难,通常SQL优化器可以从中获得合理的性能。选项4或5将是我的选择。如果您的数据很重要,我不会用选项3丢弃您的类型信息。(您可以尝试自己实现完整类型检查,但这是一项相当大的工作,数据库引擎已经为您完成了这项工
- 确保
具有CustomFields
列。DataType
- 对
使用基于UDF的检查约束,以确保CustomFieldValues
指定的列不为空CustomFields.DataType
- 您还需要一个标准的检查约束,以确保只有一个非空值
- 对
- 关于外键,我将把它们建模为一个单独的
。数据类型
- 每个潜在的交叉表引用都需要自己的列。这很好,因为它保持了引用完整性
- 无论如何,您都必须在应用程序代码中支持这些关系,因此它们在数据库中硬编码的事实实际上并不限制功能
- 如果您使用的是ORM,这也会很好地与您的ORM配合
- 对于选项5,使用中间表对关系进行建模。
- 您仍然会有一个
,但是只有CustomerCustomFieldValue
和CustomerID
列CustomFieldValueID
- 您仍然会有一个
- 每一步都要仔细考虑你的限制。这是一件棘手的事情,一个失误就可能导致彻底的失败
另外,XML可能也是一个不错的选择。从直接的经验来看,我不太了解这一点,但这是我在开始数据设计时考虑的选项之一,看起来很有希望。我同意下面的海报,选项3、4或5最有可能是合适的。但是,您建议的每个实现都有其好处和成本。我建议根据您的具体要求选择一个。例如:
选项1缺点:自定义字段是泛型的,因此没有强类型字段。数据库表是低效的、按大小排列的,有许多永远不会使用的无关字段。需要预计允许的自定义字段数
选项2缺点:在自定义字段上不可能执行DB操作。如果您只需要稍后显示自定义字段,或者只对每个客户的数据进行较小的操作,那么这是最好的
注:如下所述,“设计模式”一词通常指的是面向对象编程。您正在寻找一个数据库设计问题的解决方案,这意味着大多数关于设计模式的建议都不适用。我目前正在处理一个有同样问题的项目,我选择使用选项3,但我添加了一个FieldType字段和一个ListSource字段以防FieldType=“list”。ListSource字段可以是查询、sql视图、函数名,也可以是生成列表选项列表的内容。在我的情况下,尝试存储这样的字段的最大问题是该字段列表可能会更改,并且允许用户稍后编辑数据。因此,如果字段列表已更改,并且它们进入编辑状态,该怎么办。我的解决方案是,仅当列表未更改时才允许编辑,如果列表已更改,则显示只读数据。选项2的扩展是二进制序列化,而不是XML。当你问到有什么设计模式时——Martin Fowler在他的《企业应用程序架构模式》一书中称之为序列化LOB——请看我是curi
CustomerID, CustomFieldID, Value
10001, 1001, '02/12/2009 8:00 AM'
10001, 1002, '18.26'
10002, 1001, '01/12/2009 8:00 AM'
10002, 1002, '50.26'
CustomerID, CustomFieldID, DateValue, StringValue, NumericValue
10001, 1001, 02/12/2009 8:00 AM, null, null
10001, 1002, null, null, 18.26
10002, 1001, 01/12/2009 8:00 AM, null, null
10002, 1002, null, null, 50.26