MySQL如何使用SET类型来选择一个SET包含另一个SET中的一个或多个项目的记录

标签 mysql set

我有一个名为“食谱”的表格,以名为“成分”的 SET 类型列出了食谱中使用的所有食物(食谱仅限于使用少量特定成分)。

食谱表

id(整数)

菜谱名称(文本)

成分(套装)

我有另一个名为“food_types”的表。每条记录都有一个“名称”字段(例如“水果”、“家禽”、“香料”、“肉类”……)和一个名为“项目”的 SET 类型,其中包含属于该食品类型的成分。例如。对于“水果”记录,SET 可能是“苹果、橙子、梨、香蕉”。 '

食物类型表

id(整数)

类别(文本)

项目(设置)

我的问题是如何创建一个 MySQL 查询,该查询从“食谱”表中选择所有记录,该表包含“成分”集中给定“项目”集中的一项或多项。

所以用英语我的查询可能是:

“选择成分包含一种或多种水果的所有食谱”

谁能建议一个使用 MySQL 查询来做到这一点的好方法?

注意:我很欣赏有更好的方法来构建食谱/配料问题的表,但我正在寻找一种 MySQL 查询解决方案,可以使用 SET 和上述表来实现此目的。

最佳答案

这是对 SET 字段的不当使用 - 您无法在不进行模式修改的情况下添加 food_type,这始终是您的结构错误的一个很好的指示。使用连接表来表示多对多关系。在本例中,创建一个表 ingredient_type,它引用具有 ingredient_idfood_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 存储的二进制性质来做到这一点。如果配方成分和类别成员之间存在重叠,则按位 AND(使用 & 运算符)中设置的位数将 > 0:

SELECT DISTINCT recipeName FROM recipes JOIN food_types ON BIT_COUNT(food_types.items & recipes.ingredients) > 0 WHERE food_types.category = 'fruit';

只有当成分和元素集定义完全相同时,这才有效。

SET 还存在其他问题:

  • 它们最多只能包含 64 项
  • 字段值的顺序始终与集合的顺序相同
  • 除简单匹配之外的大多数查询(例如匹配集合中的单个项目)都不会被索引
  • 除非定义相同,否则 SET 无法进行比较
  • 没有地方可以放置有关每个项目的附加元数据

这种方法违背了使用关系数据库的大部分要点。这是教科书上的第一范式数据库内容。我认为这样的结构的唯一目的是用作如何不这样做的示例。

关于MySQL如何使用SET类型来选择一个SET包含另一个SET中的一个或多个项目的记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26733162/

相关文章:

javascript - 合并 ES6 map /集合的最简单方法?

php - 基于 URL ID 加载图像

mysql - Rails/Mysql 复杂连接和 where 查询

java - 树集重复项

python - 这些集合操作是什么,为什么它们会给出不同的结果?

c++ - std::set<std::future> 不可能存在吗

mysql - 如何从sql中的动态表中获取数据

MySQL:通过三个主键中的两个选择行

mysql - 在squirrel sql中创建一个mysql存储过程

python - 解析和计算 boolean 集定义