2013-05-28 28 views
0

我的數據庫的某些部分需要非常靈活,以至於用戶可能決定操縱表中列的數量和/或數據類型。已經在表格中的數據應該被保留。 這給我留下了唯一的選擇,即使用nvarchar(max)作爲任何這些表中任何列的數據類型。在轉換的列上比較查詢

無論是用戶選擇將整數存儲在某個列中然後想要將該字段的所有行都存儲在特定範圍內,然後,我應該對該列的轉換值執行比較查詢,並將其轉換爲int

恐怕會出現性能災難。假設我沒有其他設計替代方案,在這種情況下我能做些什麼來提高性能?

+0

這不僅是性能上的災難,它還會使所有的查詢複雜化,首先確保你需要轉換的值實際上是你想要的數據類型 – Lamak

回答

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數據類型。這爲你想要的提供了一條替代路線。但是,它會失去最初的用戶格式(這在我遇到類似問題時非常重要)。

1

鑑於你所說的話,也許你可以爲每列添加一個額外的int列,並且如果用戶將一列放入nvarchar(max)列中,那麼將會將它填充爲int),那麼至少你只會有將數據轉換一次,而不是每次查詢它。否則,是的,你堅持轉換爲一個整數的表現不佳(因爲你必須保留早期的信息,可能不是int),以便進行任何類型的排序或數學計算。另一種可能是有一個字符串列和一個int列(以及一個觸發器來確保只有其中一個被填充),然後是一個視圖,它們將它們合併顯示以便在顯示所有記錄時進行顯示。一個meta表格告訴你客戶端正在使用哪一個可以幫助你處理查詢。不管這是一團糟。你有沒有考慮過一個nosql解決方案可能對你的需求更好?這是NoSQL的用例,數據athat是非結構化的。如果我們知道這些數據的真正用途,我們可以提出一個更好的設計方案。如果不知道更多,我會質疑任何應用程序的需求是否靈活,通常需求比用戶實際需要或將要使用的更多的靈活性以及開發者忠實地構建它,我已經看到了這個在我必須支持的每一個COTS計劃中,用戶總體上認爲他們需要靈活性 - 使其成爲一個銷售點,但發現它很難使用,以至於他們不會在實踐中使用它,有時我們需要做得更好。如果要求會使軟件運行緩慢或幾乎無法使用,則推回。)

+0

它實際上是一個維基引擎,這是[wiki模板]的部分(http://en.wikipedia.org/wiki/Help:Templates)生成器。 事情是插入數據作爲模板參數是可查詢。因此需要進行類型切換和轉換後的查詢。 我認爲你提供的一個版本(具有通用字符串列和每種類型更改的特定類型列)都可以工作。 – Vahid