2015-02-09 88 views
1

我必须用PHP每10分钟更新一个MySQL数据库中的大表(产品)。我必须使用cron作业运行PHP脚本,并从CSV文件中获得最新的产品。该表目前有~18000行,不幸的是我不知道在10分钟内会有多少变化。最重要的是我不希望用户在后台注意到更新。根据CSV每x分钟用PHP更新整个表格

这是我的想法和恐惧:

  • Idea1:我知道,有一种方法可以load a csv file into a table与MySQL,所以也许我可以用交易来截断表,并导入CSV。但即使我使用交易,只要表格很大,恐怕有些用户可能会看到空的数据库。想法2:我可以比较旧的和新的csv文件with a library,只更新/添加/删除更改的行。通过这种方式,我认为用户看不到空的数据库是可能的,但恐怕这种方法会花费大量RAM和CPU,而且我正在共享主机。

所以基本上我想知道哪种方法是最安全的更新表,完全没有用户注意到它。

+0

因为您使用的是共享主机,所以您必须谨慎对待CPU和RAM。总共约有多少行?十分钟内有多少人可能会改变?偶尔内存高峰一般是原谅的,但CPU是棘手的:你可能会发现'usleep()'在这里很有帮助,允许在盒子上的其他应用程序获得一个参考。 (并且,正如我最近发现的,无论如何,CSV导入都可以在非常小的RAM占用空间中完成)。 – halfer 2015-02-09 16:33:52

+0

感谢halfer,我更新了我的问题,并提供了更多详细信息。 – frzsombor 2015-02-09 16:50:51

+0

对于<10分钟的写入时间,18K行并不是那么糟糕。使用事务在真正的共享主机上进行一些测试。如果您认为大部分/全部都会更改,请擦除表格并重新插入,如果您认为只有少数几个将会更新,请仅更新已更改的行。 – halfer 2015-02-09 16:56:05

回答

3

假设InnoDB和默认隔离级别,您可以启动事务,删除所有行,插入新行,然后提交。在提交完成之前,用户将看到以前的状态。

事务处于打开状态(删除后)时,更新将会阻塞,但SELECT不会。由于它是用户的只读表,因此不会成为问题。在交易开放的时候,他们仍然可以通过SELECT

您可以通过阅读关于MVCC的方式了解详情。其要点是,只要有人执行SELECT,MySQL就会使用数据库中的数据加上回滚段来获取以前的状态,直到事务被提交或回退。

MySQL docs

InnoDB使用在回滚段中的信息进行 撤消一个事务回滚所需的操作。它还使用 信息构建一个行的早期版本以进行一致的读取。

只有在提交完成后,用户才能看到新数据而不是旧数据,并且只有在当前事务结束后才会看到新数据。

+0

感谢您的回答!是的,这是一张只读表格。比方说,我有一个数百万行的数据库(这不是实际情况,我只是好奇)。即使有交易,在这种情况下提交也需要一些时间,不是吗?你能告诉我在提交过程中发生了什么,如果有人在这种情况下试图从表中选择? – frzsombor 2015-02-09 16:58:21

+0

我更新了我的答案,因为评论的回复太长。 – 2015-02-09 17:24:13