2012-12-11 77 views
13

我現在有一個數據庫表設置如下(EAV - 商業上的原因是有效的):在SQL Server中使用sql_variant over varchar有什麼好處嗎?

  • 標識 - 一個int(PK)
  • 鍵 - 獨特,VARCHAR(15)
  • 價值 - VARCHAR( 1000)

這允許我將混合值作爲鍵/值對添加到我的數據庫中。例如:

1 | 'Some Text'  | 'Hello World' 
2 | 'Some Number' | '123456' 
etc. 

在我的C#代碼,我用ADO.Net使用reader.GetString(2);檢索值作爲一個字符串,然後讓我的代碼的其他地方將其轉換爲所需,例如... Int32.ParseInt(myObj.Value);。我正在考慮通過將值列更改爲sql_variant數據類型來增強我的表格,但我不知道這會有什麼好處?基本上,有我的列是sql_variant vs varchar(1000)


更清楚,我讀的地方,SQL_VARIANT被返回的數據類型爲nvarchar(4000)返回給客戶端進行調用(哎喲)!但是,在返回之前我不能將它轉換成它的類型嗎?顯然,我的代碼必須進行調整,以將值存儲爲對象而不是字符串值。我想,在我目前的情況下,使用sql_variant與其他類型的優點/缺點是什麼?哦,值得一提的是,我計劃存儲的日期時間,字符串和數值類型(int,decimal等)在value列中;我不打算存儲和blob或圖像等

+1

As [Aaron Bertrand在他的*糟糕的習慣中提到踢 - 使用錯誤的數據類型*](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/12/bad-habits-to -kick-using-the-wrong-data-type.aspx):*全部使用SQL_VARIANT * - 它不是**一個好主意。不要使用它。你沒有得到任何好處 - 但有很多缺點... –

+0

除了聲明sql_variant是壞的,你是否聲明varchar(1000)是在我確切的情況下去的方式? –

+0

您如何看待使用sql_variant會增強您的表格? –

回答

7

如果您更改類型爲sql_variant,您將不得不使用IDataRecord.GetValue方法。它將一直保持這種類型。

所以在.NET它可以讓你有這樣的代碼:

// read an object of SQL underlying data type 'int' stored in an sql_variant column 
object o = myReader.GetValue(); // o.GetType() will be System.Int32 

// read an object of SQL underlying data type '(n)varchar' or '(n)char' stored in an sql_variant column 
object o = myReader.GetValue(); // o.GetType() will be System.String 

// read an object of SQL underlying data type 'datetime' stored in an sql_variant column 
object o = myReader.GetValue(); // o.GetType() will be System.DateTime 

etc... 

當然,其設定保存時你做的一樣。只需將SqlParameter.Value設置爲不透明值,不要使用DbType。

作爲價值的各種(標準)類型的EAV是我個人認爲sql_variant很有趣的一種情況。

當然,「以SQLServer爲中心的人」(閱讀:DBA)完全不喜歡它:-)在SQL Server端,sql_variant使用起來不太實際(如註釋中所述),但如果你把它作爲一個不透明的「東西」,不必在SQL過程代碼中使用它,我認爲沒關係。所以,它在.NET/OO編程方面更具優勢。

1

sql_variant類型有其侷限性,正如Zarathos所描述的那樣。

我覺得困惑的是你提到varchar(1000),然後'ouch'關於返回一個轉換的nvarchar(4000)。

我首先要說的是,整個世界終於停止使用本地和有限的字符集並決定全部使用Unicode和UTF-8是一件好事,因此您應該更喜歡nvarchar over varchar和ntext over文本。

而且返回值是nvarchar(4000)而不是nchar(4000)。不同之處在於,任何varchar的大小都是可變的,而普通類型char的大小是固定的。返回char(4000)的元組將會發送大量的空垃圾,但使用varchar這不是問題。

好的。但是什麼是適合你的適當的數據類型?我會推薦ntext。 明天1000人今天可能是10,000人。如果你有很多文本沒有編制索引,那麼你的數據庫可能不應該決定什麼限制。這只是文字。

ntext也適合.NET,因爲它的字符串總是以Unicode編碼。 .NET中的字符串轉換爲int的速度也快於sql server。

希望這有助於

9

有關SQL變種的好處是,你可以存儲多種類型的列和你保持類型的信息。

插入到MySettings中的值('Name','MyName');插入到 MySettings值('ShouesNumber',45);插入到MySettings值 ('MyDouble',31.32);

如果你想取回類型:

select SQL_VARIANT_PROPERTY (value , 'BaseType') as DataType,* from mysettings 

,你必須:

Datatype Name   Value 
----------------------------- 
varchar Name   MyName 
int  ShoesNumber 45 
numeric MyDouble  31.32 

很不幸,這有幾個缺點:

  1. 不是很快
  2. 不是很好的支持者泰德通過ORM框架
2

我看不出它已經沒有提到,所以我會提到這一問題相當普遍的做法是這樣的一個表:

  • 標識 - INT (PK)
  • 鍵 - 獨特,VARCHAR(15)
  • 值類型 - 整數(0 - 字符串,1 - 整數,3 - 浮動)(可選)
  • 的StringValue - VARCHAR(1000)
  • INTVALUE - Intege [R
  • 的floatValue - 雙人

優點:

  • 數據保存在其適當的形式(存儲整數爲字符串浪費很多位)
  • 你可以等,其中左看中查詢(key,5)='SHOES'和IntValue> 5
  • ValueType列僅用於在鍵上使用前綴/後綴(用於檢索鍵集),並且該集可以是混合類型。即WHERE左(鍵,4)= '大小' 和值類型= 1

缺點:

  • 無處不在,你使用這個表,你必須確保你/獲取/設置正確的值列
  • 如果您決定需要/需要ValueType列,則必須確保您正確設置/設置。
+5

通過'ValueType'列和填充'StringValue','IntValue'和'FloatValue'之間的選擇,您已經成功地重新創建了一個'sql_variant',它有更多的工作要使用,並且功能更少。 –

相關問題