這是對SET字段的不恰當使用 - 如果不進行架構修改,您無法添加food_type,這總是一個很好的指示器,表明您的結構是錯誤的。使用連接表來表示多關係。在這種情況下,請創建一個表ingredient_type
,該表引用ingredient_id
和food_type_id
這兩個表。這也可以讓你有多種類型的配料,比如SET,但是更靈活。
ingredient (ingredient):
apple
orange
chicken
ginger
potato
food_type (type):
fruit
vegetable
meat
poultry
spice
ingredient_type (ingredient, type)
apple, fruit
orange, fruit
chicken, meat
chicken, poultry
ginger, vegetable
ginger, spice
potato, vegetable
recipe_ingredient (recipe, ingredient):
recipe1, chicken
recipe1, potato
recipe2, orange
recipe2, ginger
有了這個結構,你可以做的查詢是這樣的:
SELECT DISTINCT(recipe) FROM recipe_ingredient WHERE ingredient = 'orange';
會告訴你使用橘子所有的食譜。稍微複雜一些:
SELECT DISTINCT(recipe) FROM recipe_ingredient JOIN ingredient_type on recipe_ingredient.ingredient = ingredient_type.ingredient WHERE ingredient_type.type = 'fruit';
這將找到使用任何水果成分的所有食譜。
編輯:關於使用SET。
您可以通過使用SET存儲的二進制特性來做到這一點。哪裏有配方成分和類別成員,組比特中按位的數目和(使用&
運營商)之間的重疊將是> 0:
SELECT DISTINCT recipeName FROM recipes JOIN food_types ON BIT_COUNT(food_types.items & recipes.ingredients) > 0 WHERE food_types.category = 'fruit';
此,如果成分和項設置的定義將只工作是完全相同的。
還有其他的問題集:
- 他們最多隻能包含64個項目
- 字段值總是在相同的順序設置
- 不是簡單的匹配其他大多數查詢(示例以匹配集合中的單個項目)未被編入索引
- 除非定義相同,SET不能被比較
- 無處可放置關於每個項目的附加元數據
這種方法破壞了使用關係數據庫的大部分要點。這是教科書第一個常規形式的數據庫。我能看到的像這樣的結構的唯一目的是作爲一個例子來說明如何去做。
我同意這是一個更好的方式來實現我所描述的,但我的示例數據庫是一個簡單的例子,我試圖用食物而不是我使用的實物來表達。例如,就我而言,配料可以屬於多種食物類型。在使用SET和我描述的兩個表之後,我仍然在尋找一種方法來完成我的工作。 – 2014-11-04 11:59:57
在我的例子中,配料可以屬於多種類型 - 看姜和雞肉。你真的不想爲此使用SET。 – Synchro 2014-11-04 12:03:39
好的,我同意你的答案是一個更好的解決方案的配料/配方問題,但我堅持我的結構爲我的現實生活中的問題。是否可以使用我的表和我的設置創建我想要的查詢? – 2014-11-04 12:32:07