2010-07-01 104 views
3

在我的情況下,每個「項目」要麼都有屬性,要麼沒有。這些屬性可能有幾百個,所以我需要每個項目最多1000個真/假位。如何將一組布爾值存儲在MySql數據庫中?

有沒有辦法將這些位存儲在項目的一個字段?

+0

您是否需要對此進行任何類型的查詢?或者只是存儲/檢索? – Thilo 2010-07-01 04:25:31

+0

只需存儲/檢索。 – Wartin 2010-07-01 11:23:30

回答

3

如果您正在尋找以可搜索的方式執行此操作的方法,則不需要。

幾個搜索的方法(涉及多於1柱和/或表):

  • 使用一堆SET列。你只能在一組中設置64個項目(開/關),但你可能會想出一種方法來組合它們。
  • 使用3個表格:Items(id,...),FlagNames(id,name)和一個數據透視表ItemFlags(item_id,flag_id)。然後您可以使用joins查詢項目。

如果你不需要它是可搜索的,那麼你所需要的只是一種方法,在將數據放入數據庫之前序列化數據,並在將其拉出時將其反序列化,然後使用char ,或者varchar列。

  • 使用內置於您的語言(PHP的序列化/反序列化)的設施。
  • 將一系列「y」和「n」字符連接在一起。
  • 在打電話給MySQL數據庫之前,將您的值打包成一個字符串(每個字符8位),並在從數據庫中檢索數據時解壓縮它們。這是最有效的存儲機制(如果所有行都相同,請使用char [x],而不是varchar [x]),代價是數據不可搜索,代碼稍微複雜一些。
+0

位數據包。所以,只有2個解決方案在真正的比特包或正常化。 – 2010-07-01 04:58:29

0

在最糟糕的情況下,您將不得不使用char(1000)[ynnynynnynynnynny ...]或類似的東西。如果你願意打包它(例如,到十六進制是不是太糟糕),你可以用char(64)[十六進制字符]。

如果它小於64,那麼SET類型將起作用,但似乎這還不夠。

你可以使用二進制類型,但這是設計更多像電影等東西。所以我不會。

所以是的,它似乎是你最好的選擇是將它打包成一個字符串,然後存儲它。

應該指出的是,一個VARCHAR會浪費空間,因爲你確切知道你的數據需要多少空間,並且可以精確地分配它。 (有固定寬度的行是一件好事)

+1

如果他不必對這些標誌進行查詢,那麼這個答案很好。如果他想使用壓縮字符串編寫WHERE子句,這可能會很棘手(並且很難索引)。 – Thilo 2010-07-01 04:27:29

+0

非常真實。在這種情況下,我同意另一個(三個表格而不是1個)解決方案會更好。 – zebediah49 2010-07-01 04:41:10

+1

varchar不要浪費空間。答案並不是那麼好。 – 2010-07-01 05:00:04

3

我寧願喜歡的東西去:

Properties 
ID, Property 
1, FirsProperty 
2, SecondProperty 

ItemProperties 
ID, Property, Item 
1021, 1, 10 
1022, 2, 10 

然後,它會很容易地檢索的屬性被設置或不與查詢任何特定項目。

+0

我認爲查詢不會讓服務器非常開心,對於那些等待它執行的人也是如此...... – Wartin 2010-07-01 04:03:55

+1

我認爲您低估了數據庫管理員的力量。可以直接查詢 – 2010-07-01 04:34:23

0

嚴格地說,你可以使用做到這一點下面:

$bools = array(0,1,1,0,1,0,0,1); 
$for_db = serialize($array); 

// Insert the serialized $for_db string into the database. You could use a text type 
// make certain it could hold the entire string. 
// To get it back out: 

$bools = unserialize($from_db); 

這就是說,我會強烈建議在尋找替代解決方案。

根據使用情況,您可以嘗試創建與「屬性」表中的值具有多對多關係的「項目」表。這將是通用實體屬性值數據庫設計模式的標準實現,用於存儲有關一組通用對象的變量點數據。