我最近在考虑一些事情,我想知道做类似以下场景的正确方法是什么(我相信对于 DB 人来说做类似的事情是很常见的事情)。
假设您有一个产品表,如下所示(MySQL):
CREATE TABLE `products` (
`id` int(11) NOT NULL auto_increment,
`product_name` varchar(255) default NULL,
`product_description` text,
KEY `id` (`id`),
KEY `product_name` (`product_name`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
这里没有什么不寻常的。现在假设在不同的表中有一个类别的层次结构,并且有一个单独的表将多对多关系与 products 表绑定 - 这样每个产品都属于某种类别(我将省略那些,因为这不是这里的问题)。
现在到了有趣的部分——如果每个类别都要求产品项目附加一组变量。例如,计算机显示器类别中的产品必须具有 LCD/CRT 枚举字段、屏幕尺寸枚举等 - 以及其他一些类别,假设冰淇淋有一些其他变量,如风味 varchar、货架存储时间 int 等。
这里的问题在于所有产品都有一组共同的变量(id、name、description 和类似的),但是还有其他变量在类别之间不一致 - 但所有产品都应该共享共同的集合,因为最后它们都属于产品组,因此可以查询例如 SELECT * FROM products ORDER BY company_id (琐碎的例子,可能不具有代表性,但你明白了)。
现在,我看到了几个潜在的解决方案:
- 为每个产品类别生成单独的表,并在其中存储带有适当附加变量的产品 - 愚蠢且查询不友好
- 产品表与公共变量保持相同,并为每个类别创建一个单独的表,其中包含额外的将两个表与 JOIN 绑定的变量 - 标准化,但查询性能和清晰度问题 - 如何从类别中过滤产品(第一个表 - 产品)和额外的变量过滤器(即 17 英寸 LCD 显示器) - 它需要 SQL JOIN 技巧
- 产品表保持不变并添加另一个变量类型文本,例如包含其他变量的 JSON 数据 - 紧凑且整洁,但无法使用 SQL 过滤变量
我知道我在这里遗漏了一些非常明显和简单的东西——我对标准化技术有点生疏了:)
编辑:在没有成功提出这个问题之前,我一直在搜索 stackoverflow。然而,在我发布问题后,我点击了我的一个标签“规范化”,发现了几个类似的问题,导致查找“泛化专业化关系设计”。故事的重点是,这一定是我的互联网生活中第一次出现标签在搜索中真正有用的情况。但是,我仍然想听听你们的意见和意见。
编辑2:方法 2 的问题是我希望大约 1000 个专业化。类别有一个层次结构(1-4 级深),端节点添加了专门的变量 - 它们以大约 1000 个的顺序累积,因此添加专门的表来连接有点不切实际。
编辑3:由于在我的案例中存在大量属性波动,建议的“实体属性值”看起来像是要走的路。查询噩梦来了!多谢你们。