【问题标题】:How to store a PropertyBag class into database如何将 PropertyBag 类存储到数据库中
【发布时间】:2014-08-21 11:04:29
【问题描述】:

我的应用程序是在 C# 下构建的,需要动态属性处理。该动态属性由最终用户处理,在我的每个业务对象中添加和删除新字段。

因此,我的方法是在每个对象上构建一个 PropertyBag,例如:

public class Customer {

    public string Name { get; set; }
    public string Id { get; set; }
    public string Phone { get; set; }

    public PropertyBag UserProperties { get; set; }
}

我们正在实现的PropertyBag 类基于本文:

PropertyBag Article

我的问题是关于如何将这些数据存储到数据库中以备后用。

我们正在考虑以下选项:

a) 将 PropertyBag 属性序列化为 XML 并与原始对象一起存储到特定字段中。

我们的想法是这很容易实现,但会给性能增加额外的问题。

b) 使用通用实体属性值 (EAV) 表来存储所有对象属性。实体将是原始对象,赋予属性 id 并为其赋值。

这可能很难实现和维护。此外,我们必须将所有属性保留为字符串以便更好地使用。

c) 方法与 (b) 相同,但每个对象表有一个 EAV 表。

实现和维护也很棘手,但表尺寸较小。

我们目前看不到其他选项或替代方案。所以,这是我的问题:

  1. 上面给出的还有其他替代方法吗?

  2. 哪一个最适合这种应用?

任何帮助表示赞赏。

[编辑]

基于评论的更多信息:我认为需要更多上下文才能得出答案。例如:

每个包有多少个值?

其中一些可能有 10 个或更多(20 个,最多 30 个)。它们中的大多数将有 2-5 个属性。

我们预计总共会有 70-100 个业务对象。其中一些将有 10.000 个或更多寄存器。几个月后,其中 2 或 3 个将有 1.000.000 条记录。

您希望能够在数据库中搜索单个值吗?

我们将始终向前搜索,但我们的想法是进行两步搜索。首先使用 Db 级别的“真实”SQL 过滤器对“真实”属性进行过滤,然后使用 linq 过滤扩展属性。这是因为搜索纯 EAV 表会很复杂。

每个客户都有相同的属性吗?

Customers 只是一个示例,但是是的...对于同一业务类的所有对象(例如:Customers),“扩展属性”将是相同的。

【问题讨论】:

  • 我认为需要更多上下文才能得出答案。例如:每个包有多少个值?您希望能够在数据库中搜索单个值吗?每个客户是否具有相同的属性?

标签: c# sql database oracle architecture


【解决方案1】:

只有另一种选择是向您的表中添加额外的列。这对你来说可能是一个非常糟糕的主意,所以我不会费心讨论它。

A.将 PropertyBag 属性序列化为 XML

优点

  1. 易于维护
  2. 可以存储任意数量的属性

缺点

  1. 可能会使 SQL 查询编写起来非常笨拙且速度缓慢。
  2. 在 SQL Server 中的 XML 数据类型中存储不适用于某些 ORM 软件
  3. 没有参照完整性(即没有什么可以阻止您将随机 XML 放在那里会破坏您的软件)

B.使用通用实体属性值 (EAV) 表

优点

  1. 您开始获得一些参照完整性。
  2. 对值的查询更容易编写。

缺点

  1. 需要更多维护。
  2. 所有实体的值都合并到一个表中,看起来它会变得相当大。根据您的数字保守估计,您将在 3 个月内拥有 1000 万房产价值。对于 Oracle 来说不是问题,但是 1 年后呢? 2年?预计增长?
  3. 所有属性值都是字符串。文本和数字不太复杂,但请注意日期/时间值。
  4. 您很难在数据库上强制执行某些完整性。例如,如何停止将属性分配给不适用的对象?

C.每个对象的 EAV 表

优点

  1. 选项 B 中的所有内容。
  2. 更好的参照完整性,现在您不必担心将Customer 属性类型分配给Order 对象。
  3. 最好的数据库性能。
  4. 更易于管理的表大小,尤其是在您预计任何显着增长超过 3 个月估计值的情况下。

缺点

  1. 设置时间最多。
  2. 还有很多需要维护。

总结

我过去曾多次使用选项 B,但它可能会变得非常痛苦。在不知道您的设置的情况下,我的建议是使用选项 C。如果您有资源并且具有前瞻性思维(预期增长,预先担心表大小、索引等),那么这将是扩展最佳的选择。现在还值得考虑数据保留策略。例如,您是否有将来需要删除的对象?我还没有找到一个没有的数据库!所以当你需要删除一堆Customer对象时,选项B是一个潜在的性能瓶颈。

最终,只有您知道您的要求,但我希望这会有所帮助。

【讨论】:

  • 帮助很大。。感谢您的见解...顺便说一句,我们根本不使用 ORM(架构策略)。关于删除,寄存器是“标记删除”,然后在实际中批量删除。我们的想法真的很前卫...添加列将是一个简单而错误的决定...感谢 cmets。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多