用户可自定义的数据结构的设计选择?

时间:2011-02-28 09:13:29

标签: c# database-design architecture

我打算构建一个必须允许用户动态设置自己的数据模型(即创建字段,数据结构等)的应用程序。

我面临着几种技术可能性,都有缺点。 :

  1. 在管理员屏幕中,更新数据库的SQL架构以反映更改。
    • 我担心这是一个非常糟糕的主意,因为应用程序必须具有对数据库的权限。此外,如果每次单击都必须应用新的sql架构,我想我会直接在一个洞上运行。这是我在大多数用户可以自定义的应用程序中看到的方法。
  2. 在DB模式中创建一组通用额外列,并希望有足够的列用于复杂数据模型。
    • 如果我的app中不允许超过X列,这很快就会成为功能限制
  3. 将所有具有ID列和Xml列的项存储在单个表中,以存储用户定义的列。
    • 这种方法可能会删除前面提到的drawacks,因为sql架构将保持静态,但由于EF(我希望能够使用)不知道如何管理xml数据类型,我将不得不最终手动SqlCommand与XML功能,或编写自定义EF提供程序,我想这将是相当多的工作。
    • 这是Microsoft为SharePoint选择的方法......这让我觉得它更好(或者至少不那么糟糕)
  4. 创建一个“属性”表,基本上包含itemId列,属性名称列和属性值列
    • 这种方法意味着一个非常大的表(每个项目X项* Y属性)
    • 我必须以纯文本格式存储我的值,即使它是数字,例如。
  5. 我的要求是:

    • 保持代码可维护,可单元测试和所有时尚技术
    • 拥有包含大量数据的响应式应用程序
    • 拥有尽可能安全的应用程序
    • 允许用户完全自定义其应用程序(使用用户属性过滤/排序创建自定义视图)。

    我觉得正确设计的选择现在必须是好的,因为要改变后者是非常困难的。

    任何反馈都将不胜感激

5 个答案:

答案 0 :(得分:3)

一种选择是使用NoSQL数据库,例如MongoDB,它是无模式的。不需要预先定义新字段(没有架构修改令人头疼),并且不同的记录可以具有不同的字段。这是像这样的NoSQL商店的好处之一。

e.g。在mongo中,你的“桌子”可能会有两条记录:

{
    "ID" : 1,
    "FirstName" : "Joe",
    "LastName" : "Bloggs",
    "FavouriteColour" : "Blue"
}

{
    "ID" : 2,
    "FirstName" : "John",
    "LastName" : "Smith",
    "DOB" : "2000-01-01"
}

添加新字段就像开始将其包含在记录中一样简单。

根据我的经验,在像SQL Server这样的RDBMS中拥有一个完全灵活/动态的架构可能会有点痛苦并且难以实现高性能。我有你所列出的选项1)和3)的经验。当数据存储为XML时,我最终通常需要为了某些目的将数据分解为关系形式。

答案 1 :(得分:1)

必须要说的是,任何具有完全表现的人都不是100%现实。

假设您正在使用关系数据库,我会使用选项#1。您仍然有机会利用快速构建RDBMS的存储设计。您可以通过使用存储过程进行DDL更改来降低安全风险,并限制对这些SP的执行权限。

可以完成选项2,但在尝试确定窗口小部件颜色是否存储在UDFText39或UDFText52中时可能存在维护问题。

“大量数据”似乎排除了选项3,除非您使用非关系解决方案。在RDBMS中,这将非常慢。

选项#4是一个全面的坏主意,因为你不仅要混合数据域(颜色,大小等),还要混合数据类型。远离这一个。

答案 2 :(得分:0)

我会说最干净的解决方案是#4。

为每个要使用的数据类型创建一个表。 - 数值 - 字符串值 - 日期时间值 - ......

所以你没有一张令人难以置信的巨大桌子,而且你的同时也很强大。 唯一的限制: 您受限于许多受支持的数据类型。但这是恕我直言的一个自然限制。

答案 3 :(得分:0)

我认为您可以不经修改就使用EF或其他ORM框架。你需要自定义代码,但我们喜欢建立新的东西,是吗?

我看到两个不太糟糕的解决方案:

1)类似于你的1.解决方案,使用2个表,一个用于列的定义,第二个用于数据。例如,您的定义表可能如下所示:

 
 Name       Type    Description
 MyColumn1  int     int column
 MyColumn2  string  string column

数据表包含填充实际数据的通用命名列。

 
Col1    Col2
1      string 1
2       string 2

当您查询“数据类型”时,您会读取“定义”,然后查询实际数据。您可以在定义表中存储其他属性,例如验证器......

3)如果您使用的是MS SQL> = 2008,则第三个解决方案看起来很不错。我仍在为每个“数据类型”推荐单独的表。

我不推荐解决方案2,它看起来像一个糟糕的黑客。 解决方案4.看起来很干净,但这种方法不适合大型数据集。

答案 4 :(得分:0)

看起来这将是EAV模式(实体属性值)的一个很好的候选者,它类似于您描述的选项之一。

Entity Attribute Value模式。

如需进一步阅读更多概念,请阅读本文> Attribute-value-system