何时应该为
分隔字段修改 2.一般情况下我应该何时将它们分开(至少在品牌,国家,类型,操作系统以下的例子中是候选的并且能够在单独的表中)
例如我有产品表,我想要过滤:
对于哪些字段我应该有多对一关系的单独表?
答案 0 :(得分:1)
如果要完全规范化所有内容并避免冗余数据,只需在主表中使用外键引用,则为所有重复的产品属性创建单独的表。除了你提到的样本列表中的“价格”之外,几乎所有的东西都是。
否则,仅出于搜索过滤的目的,您不一定需要将它们中的任何一个放在单独的表中。只需将您匹配的WHERE
条件与单个表格进行叠加即可。你所关注的不是搜索问题,而是更多的一般数据库和后端设计问题。
另请注意,如果您需要同时匹配多个搜索条件,那么如果您将数据分成多个表,则查询可能会因多个联接而变得昂贵。您只能在单个表中创建多列索引,并且您可能希望为最常见类型的产品属性组合查询创建联合索引。
答案 1 :(得分:1)
对于大型"产品表",教科书使用标准化(用于更改公共字符串的单个位置)不适用。相反,您需要平衡空间(冗余存储)和速度(搜索成本)和便利性(KV架构导致丑陋的代码)。
不要正常化'连续值,例如价格,屏幕大小,像素,浮点数,日期或其他简单数值。如果你需要搜索一个WHERE screen_size BETWEEN 20 AND 30
,但是你已将其标准化,那么这将特别糟糕。
不要正常化"小"的东西。示例:两个字母的国家/地区代码(CHAR(2) CHARACTER SET ascii
)。您可能需要有关国家/地区的更多信息的表格,但请使用2个字母的代码作为其PRIMARY KEY
。
对于小型静态列表,请考虑ENUM
。例如,gender ENUM('unknown', 'female', 'male', 'other')
。
为了钱,请使用DECIMAL
。对于整数,请使用TINYINT
,SMALLINT
等,具体取决于最大值。在适当的时候也使用UNSIGNED
。
不要列太多。相反,添加一个厨房接收器,即带有所有稀有垃圾键值列的JSON列。价格,品牌,颜色相当普遍;有他们的专栏。但屏幕尺寸,像素和操作系统可能属于厨房水槽。不,你不能使用MySQL搜索厨房水槽 - 使用MySQL过滤可见的东西(价格等),然后使用你的应用程序(在PHP或其他)解码JSON并完成过滤。
或使用MariaDB的动态列。
my blog on EAV中的更多讨论。