2013-05-28 4 views
0

Некоторые части моей базы данных должны быть чрезвычайно гибкими до такой степени, что пользователь может решить манипулировать числами и/или типами данных столбцов в таблице. Данные, которые уже находятся в таблице, должны быть сохранены. Это оставляет мне единственную возможность использовать nvarchar(max) в качестве типа данных для любого столбца в любой из этих таблиц.Сравнение запросов на преобразованных столбцах

Будь то случай, когда пользователь выбирает хранить целые числа в определенном столбце, а затем хочет получить все строки с этим полем в определенном диапазоне. Затем я должен запустить запрос сравнения по преобразованным значениям этого столбца в int.

Я боюсь, что это приведет к катастрофе. Предполагая, что у меня нет других альтернатив дизайна, что я могу сделать для повышения производительности в этом сценарии?

+0

Это будет не только катастрофа производительности, но и усложнит все ваши запросы, предварительно подтвердив, что значение, которое вам нужно преобразовать, фактически относится к типу данных, который вы хотите. – Lamak

ответ

1

Я могу связать эту проблему. Например, приложение может вводить пользовательский ввод из электронной таблицы 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) 

выше код предназначен только для иллюстрации. Возможно, вам придется обрабатывать особые случаи, которые вам не интересны (возможно, вы думаете, что «1e5» должен быть строкой или вы можете обрабатывать числа с круглыми скобками как отрицательные числа).

Вы можете обрабатывать дополнительную часть обновления через триггер до вставки или до обновления, поэтому пользователь никогда не увидит дополнительной сложности. Вы можете предоставить представление, чтобы пользователь видел только столбцы «WhatTheUserSess».

И, наконец, SQL предлагает тип данных sql_variant. Это обеспечивает альтернативный маршрут для того, что вы хотите. Однако он потеряет первоначальное форматирование пользователя (что было важно, когда я столкнулся с подобными проблемами).

1

Учитывая, что вы сказали, возможно, вы можете добавить дополнительный столбец int для каждого столбца и триггер, который будет заполнять его как int, если пользователь помещает его в столбец nvarchar (max), тогда, по крайней мере, вы будете иметь для преобразования данных один раз, а не каждый раз, когда вы его запрашиваете. В противном случае да, вы застряли в плохо выполняющем преобразовании в целое число (что является проблематичным, поскольку вам нужно сохранить более раннюю информацию, которая может не быть int), чтобы делать какие-либо заказы или математические вычисления. Другая возможность - иметь строковый столбец и столбец int (и триггер, чтобы убедиться, что только один из них заполнен), а затем представление, которое объединяет их для отображения, когда вы показываете все записи. Мета-таблица, чтобы рассказать вам, какой клиент использует, может помочь вам в запросах wswrting. Независимо от того, что это беспорядок. Считаете ли вы, что решение nosql может быть лучше для вашего требования? Это прецедент для NoSQL, данные athat неструктурированы. Если бы мы знали реальное использование этих данных, возможно, мы могли бы предложить лучшую альтернативу дизайна.

(Turn Rant on - Лично, не зная больше, я бы поставил под сомнение необходимость того, чтобы какое-либо приложение было таким гибким. Часто требования повышают гибкость, чем пользователи на самом деле требуют или будут использовать, а разработчики послушно его создают. в каждой программе COTS, которую мне пришлось поддерживать. Пользователи в целом думают, что им нужна гибкость, что делает ее точкой продаж, но так трудно использовать, что они не будут использовать ее на практике. Иногда нам нужно делать лучше отталкиваясь назад, когда требование заставит программное обеспечение работать медленно или практически невозможно использовать. Поверните Rant.)

+0

Это на самом деле вики-движок, и это часть для [wiki template] (http://en.wikipedia.org/wiki/Help:Templates) генератора. Дело в том, что данные, вставленные в качестве параметров шаблона, должны быть доступны для запроса. следовательно, необходимость переключения типов и преобразованных запросов. Я думаю, что версия того, что вы предложили (с общим столбцом строки и одним столбцом типа для каждого изменения типа), будет работать. – Vahid

Смежные вопросы