MySQL多列作为无序集

时间:2013-11-11 18:00:46

标签: mysql set

我对MySQL和SQL有点新手,所以希望这不是一个简单的问题。

我有一张桌子,在结账时代表客户购物篮中的物品。此表表示客户仅限于3个项目的情况,因此我目前在购物篮中的每个项目都有一列。它看起来像这样:

+------------------------------------------------------+
+   id   |   item1   |   item2   |   item3   |   val   |
+------------------------------------------------------+

其中val只是与购物篮相关的一些价值。项目的顺序对我的处理没有任何意义,所以理论上我希望将它们表示为无序集合。这意味着(i1,i2,i3,val)行在功能上等同于(i2,i1,i3,val)

我的问题是,我如何在我的表和/或SQL中实现这一点,以便选择(i3,i2,i1,val)将返回(i1,i2,i3,val)的行?

当我插入时,我还需要有一些能够捕捉到唯一性的东西。例如,如果我插入(i2,i3,i1,newval),我希望表格将(i1,i2,i3,val)更新为(i1,i2,i3,newval)

1 个答案:

答案 0 :(得分:0)

您可以使用客户和商品之间的0到多个关系来标准化您的模型:

-- assuming the existing table to be named `yourtable`
-- assuming your customer's table to be named `customer`
-- assuming your customer's id in the customer's table to be named `id`
-- assuming innodb (remove fk constraint if not)

CREATE TABLE `customer_item` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `id_customer` INT(10) NOT NULL, 
    `item` VARCHAR(255) NOT NULL,
    PRIMARY KEY (`id`)
)
ENGINE=innodb
SELECT NULL AS `id`, t.id AS `id_customer`, t.`item`
FROM (
    SELECT id, item1 AS `item`
    FROM
        yourtable
    UNION
    SELECT id, item2 AS `item`
    FROM
        yourtable
    UNION
    SELECT id, item3 AS `item`
    FROM
        yourtable
) t
ORDER BY t.id ASC
;

CREATE INDEX UNIQUE `idx_customer_item_cust` ON `customer_item` (`id_customer`, `item`);
ALTER TABLE `customer_item` ADD CONSTRAINT `fk_customer_item_cust` FOREIGN KEY (`id_customer`) REFERENCES `customer` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;


-- once you check the data is consistent:

DROP TABLE `yourtable`;

完成后,对于同一客户,不可能两次插入任何项目。 请注意:

  • 如果某些客户重复了某些项目
  • ,则联合选择会在创建表时跳过重复项
  • 从客户到项目的角度,您的数据已标准化
  • 从项目的角度来看,您的数据仍未正常化。您应该有一个项目表,customer_item表应该引用item表中项目的ID,而不是使用项目名称或varchars的描述。