普通的高手 - 复杂的解决方案

时间:2016-10-24 21:27:21

标签: sql mariadb

我有一些用户(C1,C2,C3等)处理不同商店(St1,St2,St3,等等)的产品(aa,bb,cc,dd,ee,ff,gg,hh等) St4等。) 列表中的每个用户都想知道哪个商店可以处理哪些产品更便宜 如果用户想要获得至少以下3件事(当时一件),如何查看表以及如何查看查询:

  

1-获取自己的产品列表。例:

  镨。 St1 St2 St3 St4
  a $ 20 $ 12 $ 19 $ 22
  bb $ 31 $ 44 $ 38 $ 44
  cc $ 18 $ 12 $ 19 $ 22
  dd $ 36 $ 44 $ 38 $ 44
  ee $ 15 $ 12 $ 19 $ 22


  

2-获取最低价格列表(但大于0)并查看他/她在其他商店处理相同产品时节省的金额。例:

  镨。 St4 St1 St3 St2
  bb $ 23 $ 27 $ 26 $ 28
  ee $ 14 $ 15 $ 15 $ 20
  hh $ 36 $ 38 $ 40 $ 37
  总计73美元80美元81美元85美元   数产品3.

           

镨。 St2 St1 St3 St4
  aa $ 32 $ 33 $ 38 $ 36
  cc $ 21 $ 29 $ 27 $ 25
  ff $ 13 $ 14 $ 17 $ 20
  总和$ 66 $ 76 $ 82 $ 81
  数产品3.


  

3-获取每个商店中具有cero价格的产品列表。例:

  镨。 St1 St2 St3 St4
  kk $ 00 $ 12 $ 19 $ 22
  ii $ 00 $ 44 $ 38 $ 44

     

镨。 St2 St1 St3 St4
  ll $ 00 $ 21 $ 52 $ 20
  mm $ 00 $ 13 $ 17 $ 15



原始不好的解决方案:

CREATE TABLE usrs(     idc INT NOT NULL,     name VARCHAR(50)NOT NULL,     stores VARCHAR(50)NOT NULL,     pwd VARBINARY(72)NOT NULL,     主要关键(idc) ) 注释='顾客' COLLATE =' utf8_general_ci' ENGINE = MyISAM的;

CREATE TABLE stores(     ids INT NOT NULL,     nm VARCHAR(50)NOT NULL,     主要关键(ids) ) COLLATE =' utf8_general_ci' ENGINE = MyISAM的;

CREATE TABLE products(     idp INT(11)NOT NULL AUTO_INCREMENT,     prod VARCHAR(50)NOT NULL,     st1 MEDIUMINT(9)NULL DEFAULT' 0',     st2 MEDIUMINT(9)NULL DEFAULT' 0',     st3 MEDIUMINT(9)NULL DEFAULT' 0',     st4 MEDIUMINT(9)NULL DEFAULT' 0',     主要关键(idp) ) COLLATE =' utf8_general_ci' ENGINE = MyISAM数据;

INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(aa,14,20,13,17);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(bb,33,29,38,33);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(cc,19,20,00,21);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(dd,22,29,25,33);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(ee,30,00,35,29);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(ff,10,14,11,13);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(gg,00,00,00,00);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(hh,16,22,30,10);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(ii,23,34,34,26);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(jj,41,32,39,41);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(kk,25,29,26,19);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(ll,24,27,10,24);
INSERT INTO产品(prod,st1,st2,st3,st4)VALUES(mm,29,41,37,36);


当商店数量超过2且用户数超过1时,我不知道所有表格的样子。 在我的解决方案中,我必须在用户或商店增加时手动更改表。我理解这里需要表之间的关系,但我不知道它。不好,非常糟糕...
提前谢谢!

1 个答案:

答案 0 :(得分:0)

您可以更改解决方案,以便获得将商店与产品相关联的价格清单。

价格将是产品,商店和价格的元组。

然后,您可以在此表上选择左连接。 where子句可以具有指定的商店ID,价格要求和/或产品ID。

示例:

为了更清晰,我修改了表格的名称。在MariaDB上测试的示例。

首先,我将使用的模型:

CREATE TABLE `stores` (
    `id` INT NOT NULL,
    `name` VARCHAR(50) NOT NULL,
    PRIMARY KEY (`id`)
);

CREATE TABLE `products` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(50) NOT NULL,
    PRIMARY KEY (`id`)
);

CREATE TABLE `prices` (
    `product_id` INT(11) NOT NULL,
    `store_id` INT NOT NULL,
    `price` DOUBLE NOT NULL,

    CONSTRAINT productIdToStoreID UNIQUE (product_id, store_id)
);

以下是我填充数据库的方法

INSERT INTO stores (id, name) VALUES (10, "Foo's Fun");
INSERT INTO stores (id, name) VALUES (20, "Bar's Barn");

INSERT INTO products (id, name) VALUES (10, "0xC0C0C01A");
INSERT INTO products (id, name) VALUES (20, "0xDEADBEEF");

INSERT INTO prices (product_id, store_id, price) VALUES (10, 10, 1.50);
INSERT INTO prices (product_id, store_id, price) VALUES (10, 20, 1.60);

INSERT INTO prices (product_id, store_id, price) VALUES (20, 10, 40);
INSERT INTO prices (product_id, store_id, price) VALUES (20, 20, 35);

以下是您可以编写的查询的起点:

SELECT store_id, price FROM prices WHERE product_id = 10; -- All prices for product with id 10
SELECT store_id, price FROM prices WHERE product_id = 10 ORDER BY price ASC LIMIT 1; -- Get Cheapest Price and Store for product 10

SELECT stores.name, price FROM prices LEFT JOIN stores ON (stores.id = store_id) WHERE product_id = 10 ORDER BY price ASC LIMIT 1; -- Get the Store name and price.

<强>动机:

我们需要一种可以关联n个商店,m个产品的方法。 (不确定用户去哪里)。我们需要一个可以容纳的数据结构:

  1. 如果商店有商品(相反,如果商品在商店)。我们可以看到这是一对多关系。 SQL数据库往往针对这种类型的关系进行了优化。
  2. 商店的商品价格。
  3. 因此,我们创建了一个表格,该表格将产品与商店唯一地链接起来,并附带价格的额外元数据。

    正如您所指出的,替代方案是一个包含所有商店作为列的表。但是,这根本不能很好地扩展,因为为了添加,删除或更改存储的名称将是O(n)更新。在生产环境中,这将是有害的,因为这可能会锁定数据库。但我离题了。

    此解决方案允许将商店列表和产品列表与实际产品分离,从而解决了此问题。如果产品的商店存在价格,则有一行。这意味着空间复杂度最差的是O(n),但实际上会少得多,因为并非所有商店都拥有所有产品。