2013-10-10 77 views
-1

什麼是在MySQL中存儲選項的最佳方式?作爲與每個字符串關聯的描述性字符串或整數。將選項存儲爲描述性字符串或數字?

比方說,我有這樣的疑問在我的UI:

什麼是你最喜歡的冰淇淋口味?

  • 香草
  • 巧克力
  • 草莓

是更好地存儲那些在DB爲1,2,3中的INT(1)字段或作爲字符串香草,巧克力,或草莓,在CHAR領域?我知道INT字段會更快,但是除非有成千上萬的行,否則可能不會很劇烈。

如果他們存儲爲字符串,然後我不需要做任何額外的PHP代碼,而如果他們存儲爲數字,我必須確定1 =香草的價值,等等。

這是什麼普遍的共識?

+0

您的行中至少應有一列作爲主鍵/索引運行,可能會自動增量。這是一種很好的做法,因爲它允許您通過引用ID號來編輯任何其他字段。否則,如果你想改變「Vanilla」,你將不得不直接編輯你的MySQL數據庫。 (好吧,不完全是,但你知道我的意思,這可以讓你唯一標識行。) – Jason

+0

@Jason,我有一個主要列,但是這與此無關。我只是問什麼是存儲數據的首選方法。 – zen

+0

EAV結構會讓你做這兩件事,但這比你看起來需要的複雜得多。在確定使用什麼方法時,問問自己以後需要做些什麼來改變它。如果你使用INT來存儲它,你必須改變你的代碼來添加標籤,如果你添加一個新的味道。爲了簡單起見,我已經使用了字符串,因爲你已經有了一個主鍵。 – Jason

回答

1

與關係型數據庫通常的做法是讓一個新的表名爲icecream_flavor或whatver。然後,您可以在以後添加新的口味,並且您的程序可以在詢問時提供所有當前的口味選擇。您可以按表ID存儲選項(整數)。

+0

如果我還有其他10個類似的問題會怎麼樣?你期望有10個關係表嗎?這似乎是我每次想要檢索一些簡單的信息時都必須加入表格。這不是核心功能,只是存儲在用戶表中的用戶配置文件問題。 – zen

+0

不,在這種情況下,你可以提供'things'和'thing_options'(抱歉,這不是很具描述性)。所以,冰淇淋將是一個'東西',而草莓是這個東西的選擇。 'thing_options'表將提供一個唯一的鍵'id'和一個外鍵'thing_id'。那麼你可以在'users'和'thing_options'之間有'favourite_things'這個多對多的東西。現在你可以存儲關於一個人最喜歡的東西的任意信息。 *例如*「玫瑰和雨滴在小貓上,明亮的銅水壺和溫暖的羊毛手套...」 – paddy

+0

讓我試着用不同的方式。你有一個'用戶'表,包含所有的用戶信息,比如'name','email','password'等等。假設我們也想存儲一個美國狀態。你只需要將'state'作爲字符串存儲在'users'表中,或者爲狀態創建一個單獨的表,然後將它與'users'表中的'state'字段相關聯? – zen

0

我建議你保持主索引爲int。這樣做的最簡單的原因是您目前不知道的,並允許您的數據模型發展。

假設你的例子,如果你用實際的單詞,並在六個月內,你決定也放入一個大小 - 單勺,雙勺等,你突然有一個問題作爲你認爲是獨特的主鍵突然有多個條目爲每個味道。另一方面,如果你使用數字格式,你可以很容易地擁有許多變種的香草,而且一切都很開心。

在這種情況下,我也建議保持實際主密鑰作爲密鑰,僅此而已。添加另一個具有風味的列,或創建一個查找表來存儲每個項目的實際屬性。如果您保留一個數字格式,但ID號爲Vanilla,則基本上會遇到與以前相同的問題,請將ID保留爲ID,並將您的詳細信息分開。

爲了保持數據有關的項目,你可以使用這樣的事情:

Master Table 
ID  Name 
1  Ice Cream 

Properties Table 
ID  Type 
1  Flavour 
2  Size 

Property Table 
ID  PropID Detail 
1  1   Vanilla 
2  1   Strawberry 
3  2   Single Scoop 
4  2   Double Scoop 

MasterToProperty 
MasterID  Property PropID 
1   1   1 
1   2   4 

這基本上是給你的選項數量不受限制,並添加你想要的任何東西(例如用於巧克力芯片中的條目)只是添加幾行數據而不是表格更改的問題。

+1

我明白你在說什麼,但你把它看作是一個「冰淇淋網站」。我發佈的問題可能很糟糕,但想象一下包含10個選擇題的用戶個人資料頁面。它們不是網站的核心功能,並且可能永遠不會有幾個選項可供選擇。 – zen

+0

@zen用我給你的簡單數據模型,你幾乎可以做任何你喜歡的事情,而不僅僅是冰淇淋:) – Fluffeh

1

如果水稻答案是不是一種選擇,那麼你應該將值存儲爲ENUM。

雖然ENUM是相當相當於TINYINT(1)。 如果您讓用戶選擇的值已經預先固定,ENUM只是答案,否則您將不得不編輯表格。但是如果你使用ENUM,MySQL插入時優化引擎,並從ENUM中選擇。這是明顯的選擇,例如(男性\女性)。

否則您的問題的答案是TINYINYT(1),這是CHAR和INT(1)中最快的。

0

如果每個用戶都可以通過某個唯一的密鑰(比如電子郵件地址)進行識別,那麼您可能會發現您不需要數字ID。

當你控制選項(所以你不會得到香草,香草香草等)時,保持風味作爲一種風味,向我建議你存儲真正的價值(香草)。

這樣可以避免連接,並在瀏覽時使數據庫數據有意義。

您可以添加一個索引到數據庫的flavor列,這樣您就可以非常便宜地「顯示所有偏好vanilla的用戶」。

(如果可能有無限的選擇,存儲,那麼也許你應該使用NoSQL數據庫調查)如果你有一個恆定的值的集合

+0

這基本上就是我在想什麼。將數據存儲爲字符串,以便每次我想要檢索簡單值時都不必進行加入。選項的數量也不太可能改變,這就是爲什麼每個問題都有單獨的表格看起來像是過度殺傷的原因。 – zen

1

,你就不會涉及該值與另一個數據在你的數據庫(有關每種類型的冰淇淋的信息),可以使用MySQL的所謂ENUM

+0

我不知道ENUM。 ENUM比CHAR或VARCHAR更快嗎?我問的原因是,如果我在UI中添加另一個選項,我將不得不將其添加到ENUM字段中,而對於CHAR或VARCHAR,我不會。 – zen

+0

@zen你是對的。無論如何,ENUM比CAHR或VARCHAR要快得多,因爲MySQL實際上並沒有在字段中存儲文本值,而只是表示每個值的數字值。 1代表香草,2代表巧克力等。我認爲更新一個領域不會導致很多問題 –

0

設置數據庫這樣特殊的字段類型:

Questions 
id, question_text 

ex. (1, "What is your favorite ice cream?") 

Options 
id, question_id, option_text 

ex. (1, 1, "Vanilla") 

Responses 
id, user_id, question_id, option_id 

ex. (1, 421, 1, 1) 

你也應該拋出一些createdmodified字段填入每個表中以便跟蹤更改。