mysql - 在 MySQL 数据库中存储组合值 - 位屏蔽、外键、联结表或什么?

标签 mysql sql database combinatorics

我正在创建一个 MySQL 数据库,其中的表包含有关不同类型产品的信息。

举个例子,假设表 1 包含自行车,表 2 包含 T 恤。

我希望能够存储有关每个表中每个项目的颜色等信息。

例如,表 1 中可能有一辆蓝色和黄色的自行车,表 2 中可能有一件红色、绿色和橙色的 T 恤。

最初,我打算将颜色信息作为二进制数存储在每个表中,并使用位掩码来找出特定对象的颜色(即 1 = 红色、2 = 蓝色、4 = 绿色、8 = 橙色 - 如果值为 5,对象为红色和绿色)。我打算有一个外键表,其中包含所有单色的值(即红色 = 1,绿色 = 4),并使用该表中的值的总和作为位掩码。

我认为这样做会“更快”,但在做出决定之前,我已经“谷歌搜索”这个主题几周了,发现拥有外键表“更快”,因此可以使用索引。 (即,如果您想查看颜色值设置为 13 的 T 恤是否包含红色和绿色,而不是执行 "13 & 5",您可以检查外键表中的第 13 行以查看是否红色和绿色的值设置为 1。)

问题是,我使用的颜色列表目前有 26 种,而且我预计它会增加。 (我试图不超过 31 种颜色,因此我可以使用 INT 列来存储值,其中 0 =“无”。)如果我要创建一个外键表来涵盖 31 种颜色的所有可能组合,那么它将必须有 2,147,483,647 行和 32 列(每种可能的颜色对应一个真/假列)。每次添加另一种颜色时,我都必须将表中的行数增加一倍(例如,添加一种颜色将需要 2147483648 行)。

我认为最好制作一个像这样的“连接表”:

+----------+------------+
| shirt_id |  color_id  |
+----------+------------+
|        1 | 1 (Red)    |
|        1 | 4 (Green)  |
|        1 | 8 (Orange) |
|        2 | 2 (Blue)   |
|        2 | 4 (Green)  |
+----------+------------+

那么就不需要一个巨大的表格来列出所有可能的组合(其中绝大多数可能永远不会被使用)。问题是,每种产品类型都必须有联结表,并且会有大量的产品类型,这意味着大量的联结表。

我使用颜色作为示例,但实际上我也计划对其他几个“可堆叠”值执行此操作(例如,单个对象可以由硬木、铝、玻璃、刨花板和 ABS 组成)塑料、PVC 和纸板...等等,全部同时进行)。

我的问题是,处理此类情况最有效的方法是什么?是否有一种我没有想到的方法比这些方法更受欢迎?

我仅使用颜色作为示例 - 数据库实际上会有许多这样的“可堆叠”属性(例如 Material 、纤维类型、纹理、表面处理等),这些属性可以应用于多个产品类型,并且“产品”本身将是“通用”的,并且具有“可堆叠”值,该值指示组成它们的组件的类型(例如,包括包装在一起的自行车和 T 恤的“产品”) .

写完这篇文章后,我想使用多个连接表将是最有效的方法。但作为一名“老派程序员”,我很难理解这样的想法:仅针对产品组件/颜色组合制作[例如] 30 个不同的连接表可能比直接分析位“更可取”以二进制值表示。 (我确实意识到 MySQL 不是任天堂娱乐系统......)

最佳答案

我曾经在不同域的字段上实现过位屏蔽。然而,这种情况显然会带来很大的性能改进,因为它可以避免连接 8~10 个表。位掩码速度非常快,尤其是在字段已建立索引的情况下。
对于 32 位字段的索引,最多将进行 31 次比较来查找结果行。
如果没有索引,它仍然必须对每一行执行位比较。

然而,还有一个很大的“如果”。这并不容易维护,而且衬衫颜色始终会受到位长度的限制,在您描述的情况下,我真的会选择联结表,并且只需确保外键上有索引即可。

关于mysql - 在 MySQL 数据库中存储组合值 - 位屏蔽、外键、联结表或什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31502363/

相关文章:

node.js - 如何增加 Mongoose 中子文档的属性?

sql - sp_helptext 更改我的缩进

sql - 将 SQL Query 中两列之间的百分比计算为另一列

c++ - 类似 Hibernate 的 C++ 框架

java - Sonarqube 抛出 MySQL 的 JDBCError

mysql - 无法将两个表合并为一个表

python - 使用 Django,如何添加引用同一个表的外键列?

php - 使用 PHP 当变量为空时更新 SQL 表字段

Java SQL 迭代 2 结果集并合并它们

sql - 错误代码 1064 MySQL