2009-09-09 54 views
3

我接管了需要重寫的ASP.NET應用程序。我需要複製的此應用程序的核心功能修改了通過ODBC從第三方軟件訪問的SQL Server數據庫。以編程方式向SQL Server數據庫添加列

第三方應用程序創建代表由用戶生成的打印機標籤的文件。這些標籤文件直接引用ODBC源的字段。表格的每一行代表填充標籤字段的產品。 (因此,在這些文件中直接引用表格的列名稱)。

ASP.NET應用程序允許用戶通過添加或編輯創建/更新標籤引用的這些字段的數據代表產品的特定行。

它還允許偶爾添加新字段......它實際上在標籤引用的核心表中創建一個新列。

我的問題:我從來沒有編程過修改現有表格的列。現有的應用程序似乎很好地處理了這個功能,但在我在新應用程序中盲目地做同樣的事情之前,我想知道這樣做有什麼樣的缺陷,如果有的話......並且如果有任何明顯的替代方案。

回答

1

這很大程度上取決於您想要針對這些表運行的查詢。 KVP的主要缺點是更復雜的查詢可能變得非常低效。

兩者的「混合」方法可能很有趣。

將要查詢的值存儲在專用列中,並將剩餘的值留在XML blob中(MS SQL具有很好的功能甚至可以在XML內部查詢)或者在KVP包中。就我個人而言,我真的不喜歡數據庫中的KVP,因爲您無法再構建特定的應用程序邏輯。

另一種方法就是根本不建模特定列。您可以創建通用的「自定義屬性」表,如:屬性1,屬性2,屬性3,屬性4(針對所需的數據類型等)。然後向數據庫添加元數據,描述AttrX對特定類型打印機標籤的含義。

同樣,它真的取決於你最終如何使用這些數據。

3

將太多的列添加到表中時,可能會出現問題,並且如果性能是一個考慮因素(涵蓋索引不適用,可能會執行昂貴的書籤查找),您必須小心。

另一種選擇是鍵值對結構:Key Value Pairs in Database design,但也有缺陷,您最好創建新列,正如您所建議的那樣。 (KVPs適用於設置)

+0

Yeap-這是一個關於KV對的SO帖子 - http://stackoverflow.com/questions/126271/key-value-pairs-in-relational-database – RichardOD 2009-09-09 15:20:43

1

一個風險是表變得太寬。我曾經維護一個可怕的應用程序,當新值被添加到某個XML時(出於某種原因,它認爲所有內容都是字符串日期或數字,因此創建了3列),「自動」添加了3列。

還有其他技術,如序列化BLOB或設計不同的表格可能有所幫助。

2

我認爲的一個選擇是使用KVP表來存儲動態「列」(如Mitch首先提到的那樣),將產品表與基於產品ID的KVP表結合起來,然後轉動結果以獲得所有結果結果集中的動態列。


編輯:沿着這些路線的東西:

準備:

create table Product(ProductID nvarchar(50)) 

insert Product values('Product1') 
insert Product values('Product2') 
insert Product values('Product3') 

create table ProductKVP(ProductID nvarchar(50), [Key] nvarchar(50), [Value] nvarchar(255)) 

insert ProductKVP values('Product1', 'Key2', 'Value12') 
insert ProductKVP values('Product2', 'Key1', 'Value21') 
insert ProductKVP values('Product2', 'Key2', 'Value22') 
insert ProductKVP values('Product2', 'Key3', 'Value23') 
insert ProductKVP values('Product3', 'Key4', 'Value34') 

檢索:

declare @forClause nvarchar(max), 
     @sql nvarchar(max) 

select @forClause = isnull(@forClause + ',', '') + '[' + [Key] + ']' from (
    select distinct [Key] from ProductKVP /* WHERE CLAUSE */ 
) t 

set @forClause = 'for [Key] in (' + @forClause + ')' 

set @sql = ' 
select * from (
select 
    ProductID, [Key], [Value] 
from (
     select k.* from 
     Product p 
     inner join ProductKVP k on (p.ProductID = k.ProductID) 
     /* WHERE CLAUSE */ 
    ) sq 
) t pivot (
    max([Value])' + 
    @forClause + ' 
) pvt' 

exec(@sql) 

結果:

ProductID Key1  Key2  Key3  Key4 
----------- --------- --------- --------- ------- 
Product1 NULL  Value12 NULL  NULL 
Product2 Value21 Value22 Value23 NULL 
Product3 NULL  NULL  NULL  Value34 
相關問題