Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/83.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 比较转换列上的查询_Sql_Sql Server_Database_Database Design - Fatal编程技术网

Sql 比较转换列上的查询

Sql 比较转换列上的查询,sql,sql-server,database,database-design,Sql,Sql Server,Database,Database Design,我的数据库的某些部分需要非常灵活,以至于用户可能决定操纵表中列的数量和/或数据类型。但应保留表中已有的数据。 这使我有了唯一的选择,可以使用nvarchar(max)作为这些表中任何列的数据类型 在这种情况下,用户选择将整数存储在特定列中,然后希望获取该字段在特定范围内的所有行。然后我应该对该列的转换值运行一个比较查询,将其转换为int 我担心这将是一场性能灾难。假设我没有其他设计备选方案,在这种情况下,我能做些什么来提高一些性能?根据您所说的,也许您可以为每列添加一个额外的int列和一个触发器

我的数据库的某些部分需要非常灵活,以至于用户可能决定操纵表中列的数量和/或数据类型。但应保留表中已有的数据。 这使我有了唯一的选择,可以使用
nvarchar(max)
作为这些表中任何列的数据类型

在这种情况下,用户选择将整数存储在特定列中,然后希望获取该字段在特定范围内的所有行。然后我应该对该列的转换值运行一个比较查询,将其转换为
int


我担心这将是一场性能灾难。假设我没有其他设计备选方案,在这种情况下,我能做些什么来提高一些性能?

根据您所说的,也许您可以为每列添加一个额外的int列和一个触发器,如果用户将一列放入nvarchar(max),该触发器将作为int填充列)则至少只需转换一次数据,而不是每次查询数据。否则,是的,为了进行任何类型的排序或数学计算,您将不得不执行性能不佳的整数转换(whcih是有问题的,因为您必须保留可能不是int的早期信息)。另一种可能是有一个字符串列和一个int列(以及一个触发器以确保只填充了这两个列中的一个),然后有一个视图将它们合并在一起,以便在需要显示所有记录时显示。一个元表可以告诉您客户机正在使用哪个元表,这有助于您进行wswrting查询。不管这是什么乱七八糟。您是否考虑过nosql解决方案可能更符合您的要求??这就是NoSQL的用例,数据是非结构化的。如果我们知道这些数据的实际用途,我们就有可能提出更好的设计方案


(打开Rant——就我个人而言,我不知道更多,我会质疑任何应用程序是否需要如此灵活。通常,需求增加的灵活性比用户实际需要或将要使用的要多,开发人员尽职尽责地构建它。我在我必须支持的每一个COTS程序中都看到了这一点。用户通常认为他们需要灵活性-m将其作为一个销售点,但发现它太难使用,以至于他们在实践中不会使用它。有时,我们需要更好地推回需求会使软件运行缓慢或实际上无法使用的情况。请关闭。)

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

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

第二部分是将值存储为数据库操作的合理方式。我将根据应用程序决定一组基本类型,可能只是float和datetime。然后,当用户插入值时,您可以进行转换并在单独的列中设置值。表中可能有如下列:

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)
然后,插入逻辑如下所示:

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”应该是字符串,或者您可能希望将带括号的数字作为负数处理)

您可以通过before insert或before update触发器处理更新的额外部分,这样用户就不会看到额外的复杂性。您可以提供一个视图,以便用户只看到“WhatTheUserSess”列


最后,SQL确实提供了
SQL\u variant
数据类型。这为您提供了另一种选择。但是,它会丢失初始用户格式(当我遇到类似问题时,这一点很重要).

这不仅会造成性能灾难,而且还会使所有查询复杂化,首先要确保需要转换的值实际上是您想要的数据类型,这实际上是一个wiki引擎,这是生成器的一部分。问题是作为模板参数插入的数据是可以查询的eed用于类型切换和转换查询。我认为您提供的版本(有一个通用字符串列,每个类型更改有一个特定于类型的列)可以工作。