首页 文章

MySql - 产品变体表(宽表) - 唯一的NULL

提问于
浏览
0

我有一个产品表和一个product_variants表(一对多) .

product_variants表具有以下结构:

CREATE TABLE product_variants (
  id int(11) NOT NULL AUTO_INCREMENT,
  id_product int(11) NOT NULL,
  id_colourSet int(11) DEFAULT NULL,
  id_size int(11) DEFAULT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY UNIQUE (id_product,id_colourSet,id_size),
  KEY idx_prod (id_product),
  KEY idx_colourSet (id_colourSet),
  KEY idx_size (id_size),
  CONSTRAINT fk_df_product_variants_id_colurSet FOREIGN KEY (id_colourSet) REFERENCES df_colour_sets (id_colourSet) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT fk_df_product_variants_id_product FOREIGN KEY (id_product) REFERENCES df_products (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT fk_df_product_variants_id_size FOREIGN KEY (id_size) REFERENCES df_sizes (id) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB

这些选项在编译时是已知的 . 每个选项都是外键到专用表,唯一键是所有选项的组合 .

然后我插入带有 "ON DUPLICATE KEY UPDATE ..." 语句的产品,如果变量已经存在,则查询将使用现有变量 .

问题是某些产品没有颜色,也没有尺寸 . 在这种情况下,唯一约束失败,我在product_variants表中插入了大量几乎为空的行 .

为了解决这个问题,我在相应的选项表中为每个选项创建一个“NULL”值(例如“NO_COLOR”,“NO_SIZE”),并将其用作product_variants表中选项列的默认值 .

这是推荐的解决方案吗?有没有更好的方法来构建这些数据?我真的想避免使用EAV设计 .

谢谢

1 回答

  • 1

    在几乎每种情况下,指定一个意味着“缺失 Value ”的神奇值并不是正确的解决方案 . 这就是NULL的用途 .

    还不清楚“NO_COLOR”如何用于整数 . 我猜它会映射到值0,这通常不会在自动增量列中使用 .

    您可以创建另一列作为三个唯一键列的哈希值,默认为''以避免出现空问题 . 然后对该哈希放置一个唯一约束 .

    CREATE TABLE product_variants (
      id int(11) NOT NULL AUTO_INCREMENT,
      id_product int(11) NOT NULL,
      id_colourSet int(11) DEFAULT NULL,
      id_size int(11) DEFAULT NULL,
      option_hash binary(16) NOT NULL,
      PRIMARY KEY (id),
      UNIQUE KEY (option_hash),
      KEY idx_prod (id_product),
      KEY idx_colourSet (id_colourSet),
      KEY idx_size (id_size),
      CONSTRAINT fk_df_product_variants_id_colurSet FOREIGN KEY (id_colourSet) REFERENCES df_colour_sets (id_colourSet) ON DELETE NO ACTION ON UPDATE NO ACTION,
      CONSTRAINT fk_df_product_variants_id_product FOREIGN KEY (id_product) REFERENCES df_products (id) ON DELETE NO ACTION ON UPDATE NO ACTION,
      CONSTRAINT fk_df_product_variants_id_size FOREIGN KEY (id_size) REFERENCES df_sizes (id) ON DELETE NO ACTION ON UPDATE NO ACTION
    ) ENGINE=InnoDB;
    
    CREATE TRIGGER product_variants_ins BEFORE INSERT ON product_variants
    FOR EACH ROW SET option_hash = UNHEX(MD5(CONCAT_WS('|',
        COALESCE(id_product, ''),
        COALESCE(id_colourSet, ''),
        COALESCE(id_size, ''))));
    
    CREATE TRIGGER product_variants_upd BEFORE UPDATE ON product_variants
    FOR EACH ROW SET option_hash = UNHEX(MD5(CONCAT_WS('|',
        COALESCE(id_product, ''),
        COALESCE(id_colourSet, ''),
        COALESCE(id_size, ''))));
    

相关问题