何时应该在数据库设计中将字段与另一个表(规范化)分开?

时间:2015-06-24 16:29:37

标签: mysql database database-design entity-attribute-value

何时应该为

分隔字段
  1. 过滤搜索?
  2. 修改  2.一般情况下我应该何时将它们分开(至少在品牌,国家,类型,操作系统以下的例子中是候选的并且能够在单独的表中)

    例如我有产品表,我想要过滤:

    • 屏幕尺寸
    • 品牌
    • 颜色
    • country build
    • 类型(平板电脑,智能手机,简单,)
    • 操作系统
    • 相机像素
    • 依旧......

    对于哪些字段我应该有多对一关系的单独表?

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。对于整数,请使用TINYINTSMALLINT等,具体取决于最大值。在适当的时候也使用UNSIGNED

不要列太多。相反,添加一个厨房接收器,即带有所有稀有垃圾键值列的JSON列。价格,品牌,颜色相当普遍;有他们的专栏。但屏幕尺寸,像素和操作系统可能属于厨房水槽。不,你不能使用MySQL搜索厨房水槽 - 使用MySQL过滤可见的东西(价格等),然后使用你的应用程序(在PHP或其他)解码JSON并完成过滤。

或使用MariaDB的动态列。

my blog on EAV中的更多讨论。