2009-11-14 64 views
1

以下情景:您在C#中有幾個與SQL Server中的Enum-ish表綁定(實際上由其生成)的標誌枚舉。假設您是分銷商,並且您允許您的分銷商指定他們運送到的美國州。作爲一個輝煌和優雅的軟件工程師,你實施這些爲按位組合的標誌值,以節省存儲:使用64位有符號值在SQL和C#中模擬128位無符號整數?

create table USState (
    StateID bigint, StateAbbr char(2), StateName varchar(50)) 
/* insert all US States + DC into USState, StateIDs must be in powers of two */ 
/* StateID 0 reserved for 'None': */ 
create procedure GetStatesByFlag (@StateFlags bigint) as 
declare @StateIDs table 
(
StateID bigint, 
primary key (StateID) 
) 
insert into @StateIDs 
    select StateID 
    from USState 
    where @StateFlags & StateID != 0 
     or (@StateFlags = 0 and StateID = 0) 

select s.StateID, s.StateAbbr, s.StateName 
from 
    USState s join 
    @StateIDs si 
    on si.StateID = s.StateID 

甜。您可以使用按位邏輯在SQL和C#中動態地包含/排除,這使您可以即時保存複選框列表並在Asp.NET中選擇列表,同時仍然只存儲一個64位數字以保存任意組合選項。在你的過程的WHERE子句中,你不需要一個不可索引的比較運算符,除了最大爲64行的枚舉表本身。在印第安納州和加利福尼亞州發貨的每個人都可以使用平等比較和索引來搜索您的分銷商。

現在你有一個要求增加對美國領土,軍隊郵政編碼和加拿大省份的支持,並且以向後兼容的方式這樣做。有沒有削減名單到< 64項,而業務真的希望避免必須從其他領土和部門隔離舊校區國家。

你是做什麼的?

創造性的答案是讚賞,但真正的挑戰是這樣的:有沒有辦法強制相同的按位數學運算在無符號64位值工作在簽名的同時使用負空間超過64位可能的位,在C#和SQL(2008)?如果它很重要,則標誌被模擬,而不是「真正的」標誌,所以在技術上不需要使用[Flags]屬性來處理CLR枚舉。

+1

組合是的,但在這種情況下,組合就像向印第安那州和加利福尼亞州運送,而不是一個州。無論如何,也許你可以嘗試使用GUID?它們實際上是128位整數。 – kubal5003 2009-11-14 00:46:17

+1

負性空間只是64位中的一個,所以沒有。 – Joe 2009-11-14 01:45:48

+1

我遇到了完全相同的問題。你如何使用GUID來存儲數字? – arao6 2014-10-28 02:55:48

回答

5

64位值不能超過64位,甚至不使用「負空間」。如果你有64位,你有64位。您可以使用Guid獲得128位,這會暫時解決問題,但最終您需要添加其他字段。

3

在SQL Server中,你可以嘗試十進制(38,0)

這給了你38位到小數點(1E38)的左側。在二進制方面,它大約是126位(8.5E37)。它可以像一個數字一樣操縱。

但是,一種選擇是定義你想要的.NET,並在SQL Server中使用匹配的CLR data type。這樣,它可以在兩個平臺之間保持一致。

不過,我真的會考慮改變從標誌了......

+0

不幸的是,對於按位運算符,十進制類型無效。 CLR數據類型的想法很有趣,我將調查我是否可以用這個角度拉出> 64位的標誌。至於遠離標誌的情況,我通常只在預期存在十幾個或更少的可能值的地方使用它們,並且沒有其他理由來創建多對多關係。我也有一個工具可以在SQL端自動生成可索引查詢,而在.NET端爲它們包含運算符,但是我將它們的使用限制在可能節省空間和編碼時間的實例中。 – 2009-11-15 04:51:31

1

我2C:你想聰明,和你造成你自己的痛苦。位域和SQL混合不好,主要是因爲位域無法正確編制索引,並且任何搜索都必須執行完整掃描。例如。找到所有發送給AK的經銷商,您需要掃描整個經銷商的表格。此外,該解決方案不會擴展到超過64個值(如您已經發現的)。它也是不好的存儲選擇,它需要一些值爲0來存儲負面信息(缺乏關聯)。

使用單獨的表格來模擬經銷商與其所在的州/地區/省份/國家/地區之間的多對多關係。

+0

採取了點。關於索引雖然,搜索do * not *需要在經銷商表上進行表掃描。在64行最大狀態表上有一個掃描來構建索引的@StateIDs表變量,該變量包含所有按位比較的輸出。 (這項工作實際上也可以持久化,但這並不足以影響到這一點)。@StateIDs表var隨後通過值連接到經銷商表的外鍵以檢索沒有表掃描的匹配項。 – 2009-11-14 20:31:14

相關問題