【问题标题】:Preventing online shop without products while importing data导入数据时防止网店没有产品
【发布时间】:2011-10-16 12:41:46
【问题描述】:

在我的网站上,有几个供应商可以导入他们的文章。

我想为他们提供清理文章的选项(例如,删除不在 importfile 中的文章)。

我想到的第一件事是在导入之前先删除供应商的所有文章,但这可能会导致客户正在访问该网站并且看不到任何产品(特定供应商)的情况.

所以经过更多思考后,我想出了另外两个解决方案:

  1. 导入产品并记住导入/更新了哪些产品(如果它们已经存在)并删除之后不在导入中的供应商产品
  2. 导入另一个临时表中的产品,删除供应商的当前产品,然后将临时表中的产品复制到“真实”表中。

但是,这两个选项都可能存在一些问题。

  1. 假设记住所有导入/更新的产品真的是个好主意,因为有时它可能超过 100 万个产品?
  2. 是否有可能删除当前产品并将产品从临时表复制到真实表,速度如此之快,以至于访问客户看不到任何产品的可能性很小?

也许我发现的选项还有其他问题。

或者也许还有其他选择可以做到这一点?

PS

在导入时“锁定”网站/锁定客户不是一种选择。

【问题讨论】:

  • 店铺有多少并发用户?
  • @Lawrence Cherone:有什么方法可以防止顾客看到没有产品的商店,同时也能让供应商删除过时的产品
  • @Richard H:大约 50k 的东西,还在增加

标签: php postgresql database-design pdo


【解决方案1】:

当我阅读您的问题时,我想到了两个解决方案:

  1. 在导入时启动“维护模式”,但这可能不是您想要的。 抱歉没有阅读您的上一条声明。
  2. 一一导入(或删除)项目,因为这样用户在任何给定时刻最多会丢失一个产品。不过,这里有几个注意事项需要考虑:
    • 如果产品在用户购物篮中时被删除会怎样?
    • 已经购买的产品中的引用需要保持不变,以便能够在购买的产品被删除后重建账单。

此外,您可以像这样重命名 PostreSQL 中的表:

ALTER TABLE TableB RENAME TO TableC;

如果您想使用我也使用过的“临时表”解决方案,尽管在不那么关键的情况下,诚然。但请注意,至少在 MySQL InnoDB 中,您必须担心外键,如果重命名,它仍会指向旧表,例如如果从 TableA 到 TableB 有一个外键,并且您将 TableB 重命名为 TableB_old 并将 TableB_new 重命名为 TableB,那么外键将指向 TableB_old。不过,我不知道 PostgreSQL 是否是这种情况。

【讨论】:

  • 我真的很想阻止第一个选项。而第二个选项没有考虑对应该删除的产品进行什么处理。也不要认为我可以重命名临时表,因为“真实”表还包含其他供应商的产品。
  • 如果重命名,如何删除旧表?不是要提前删掉吗?
  • @PhpMyCoder:你“把它们换掉了”。表A->表A_Old; TableA_New -> TableA;
  • @PeeHaa :您可以事先创建表的副本,然后进行所有导入并将其换入,但我知道这对于大型表可能不是可行的解决方案。但我真的不明白产品被删除的问题是什么。如果您从表中即时删除产品,最坏的情况是用户将在他曾经访问过的产品页面上看到 404 错误。动态删除产品当然只有在您将产品复制到购物车/发票的情况下才可行,否则您会破坏所有现有的参考。
  • @x3ro 哦。我不熟悉那个。你的解决方案可能会更好。 +1
【解决方案2】:

我对您建议的方法有所不同:
有一个名为 vendortables setup 的表,其中包含 vendorname 或 id 列以及列出其产品的表的名称。 当供应商要导入时,为输入创建一个新表(可能是供应商名称 + 上传开始时间)。将所有数据上传到其中。完成后,获取当前供应商表的名称(在 vendortables 中)并更新,以便新表的名称与上传的供应商相关联。然后删除旧表(您在更新之前抓取的)。
这样,就不会每次都复制表数据。

例子:

SELECT * FROM vendortables
+--+-----+
|id|table|
+--+-----+
|01|test |
+--+-----+

SELECT * FROM test
+--+----+
|id|name|
+--+----+
|01|car |
+--+----+


//Import & upload new data
CREATE TABLE test1 USING('?', 'new car')

SELECT * FROM test1
+--+--------+
|id|name    |
+--+--------+
|01|new car |
+--+--------+

//Phase in new data 
UPDATE vendortables SET table='test1' WHERE id='1'

//Delete old table
DROP TABLE test

只需让 PHP 向 vendortables 询问负责显示供应商产品的表的名称。

此外,由于您提到您的网站的高使用率,您是否考虑过缓存可能会使导入期间的请求变得非常不可能。

【讨论】:

    【解决方案3】:

    创建一个删除表

    delete from del_vendor_article where vendorid='vendorid'
    

    在文章更新时执行此操作

    insert into del_vendor_article SET vendorid='vendorid', article_id='articleid'
    

    可能向他们展示将被删除的内容。然后他们可以删除他们可能想要保留的任何内容

    SELECT item FROM articles WHERE NOT EXISTS (SELECT * FROM del_vendor_article WHERE articles.articles_id = del_vendor_article.articles_id);
    

    删除未导入的项目

    delete from articles WHERE NOT EXISTS (SELECT * FROM del_vendor_article WHERE articles.articles_id = del_vendor_article.articles_id);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多