0

我的数据库的某些部分需要非常灵活,以至于用户可能决定操作表中列的数量和/或数据类型。但是应该保留表中已经存在的数据。这让我只能选择nvarchar(max)用作任何这些表中任何列的数据类型。

如果用户选择将整数存储在某个列中,然后想要获取该字段在某个范围内的所有行。然后我应该对该列的转换值运行比较查询到int.

恐怕这会导致性能灾难。假设我没有其他设计选择,在这种情况下我能做些什么来提高一些性能?

4

2 回答 2

1

鉴于您所说的,也许您可​​以为每列添加一个额外的 int 列,如果用户在 nvarchar(max) 列中添加一个将其填充为 int 的触发器,那么至少您只需转换数据一次,而不是每次查询它。否则,是的,您会遇到性能不佳的整数转换问题(这是有问题的,因为您必须保留可能不是 int 的早期信息)才能进行任何类型的排序或数学计算。另一种可能性是拥有一个字符串列和一个 int 列(以及一个确保仅填充两者之一的触发器),然后在需要显示所有记录时合并它们以进行显示的视图。告诉您客户端正在使用哪一个的元表可以帮助您进行 wswrting 查询。不管这是什么乱七八糟的。您是否认为 nosql 解决方案可能更适合您的要求?这就是 NoSQL 的用例,即非结构化数据。如果我们知道这些数据的真正用途,我们就有可能提出更好的设计替代方案。

(打开 Rant - 就我个人而言,在不了解更多信息的情况下,我会质疑任何应用程序是否需要如此灵活。通常需求增加了比用户实际需要或将要使用的灵活性更大的灵活性,并且开发人员尽职尽责地构建它。我在每一个 COTS 中都看到了这一点我不得不支持的程序。用户普遍认为他们想要灵活性 - 使其成为一个销售点,但发现它很难使用以至于他们不会在实践中使用它。有时我们需要做得更好,当要求将使软件运行缓慢或几乎无法使用。关闭 Rant。)

于 2013-05-28T19:28:57.467 回答
1

我可以解决这个问题。例如,一个应用程序可能会从 Excel 电子表格中获取用户输入,并且需要以用户看到的格式存储它。但是,一旦进入数据库,您可能对过滤和组合数据有其他要求。

你已经解决了一半的问题。通过将值存储在字符字段中,您可以存储用户想要的内容。

后半部分是存储值也作为数据库操作的合理方式。我会根据应用程序决定一组基本类型,可能只是浮点数和日期时间。然后,当用户插入一个值时,您可以进行转换并将该值设置在单独的列中。您的表可能有这样的列:

ColumnX_WhatTheUserSees nvarchar(max),
ColumnX_Type char(1) not null default 'C',  -- 'C'haracter, 'F'loat, 'D'atetime
ColumnX_Float float,
ColumnX_Datetme

然后插入逻辑如下所示:

insert into t(ColumnX_WhatTheUSerSees, ColumnX_type, ColumnX_Float, ColumnX_Datetime)
    select @ColX,
           (case when isnumeric(@Colx) = 1 then 'F'
                 when isdate(@Colx) = 1 then 'D'
                 else 'C'
            end),
           (case when isnumeric(@Colx) = 1 then cast(@Colx as float) end),
           (case when isdate(@Colx) = 1 then cast(@Colx as datetime) end)

上述代码仅用于说明目的。您可能需要处理您不感兴趣的特殊情况(也许您认为 '1e5' 应该是一个字符串,或者您可能希望将带括号的数字处理为负数)。

您可以通过插入前或更新前触发器处理更新的额外部分,因此用户永远不会看到额外的复杂性。您可以提供一个视图,以便用户只能看到“WhatTheUserSess”列。

最后,SQL 确实提供了sql_variant数据类型。这为您想要的东西提供了另一种途径。但是,它会丢失初始用户格式(当我遇到类似问题时,这很重要)。

于 2013-05-28T19:43:53.547 回答