如何使此SQL查询最有效?

时间:2012-03-06 21:22:42

标签: php mysql sql database-design

我正在创建一个网站,其中包含大量用户添加的图像。

我想从该池中随机选择一个图像,并将其显示给用户,但我想确保此用户之前从未见过这个图像。

所以我在想:当用户观看图像时,我在MYSQL中输入一行INSERT,表示“此用户已在(时间)观看此图像”。 但问题是,由于可能会有很多用户和大量图像,因此该表可以很快地迅速增加到数万个条目。

所以或者,也可以这样做: 我正在考虑为每个USER创建一行INSERT,在一个字段中,我插入一个数组所有用户已经观看过的图像。

我甚至可以对数组做到这一点: BASE64_ENCODE(gzcompress化(serialize($阵列)

然后: 反序列化(gzuncompress(BASE64_DECODE($阵列))

你觉得我应该怎么做? 编码/解码功能是否足够快,或者至少比我在帖子开头描述的传统方式更快?

这种压缩是否足以将大块数据存储到一个数据库字段中? (想象一下,如果用户观看了数千张图片?)

非常感谢

5 个答案:

答案 0 :(得分:2)

  

在一个字段中,我插入一个数组所有id

几乎在所有情况下,序列化这样的值都是不好的做法。让数据库按照自己的意图行事 - 有效处理大量数据。只要确保您的交叉表在用户字段上有索引,无论表中的行数如何,检索用户看到的图像列表都不会是一项昂贵的操作。成千上万的条目都没有。

答案 1 :(得分:0)

您应该创建一个包含UserImageViewsuser_id列的新表image_id(此外,您可以在视图中添加更多信息,例如日期/时间,IP和浏览器)。

这样可以更快地进行查询,例如“用户有哪些图像(未看到)”。

答案 2 :(得分:0)

你应该使用一张桌子。将数据序列化到数据库中的单个字段是一种不好的做法,因为DBMS不知道该数据代表什么,也不能在任何查询中使用。例如,如果您想查看哪些用户查看过图像,则无法单独使用SQL。

成千上万的参赛作品并不多,BTW。我们开发的主要应用程序有多个表,有数十万条记录,而且我们并没有那么大。某些Web应用程序具有包含数百万行的表。不要担心“太多数据”,除非它开始成为一个问题 - 该问题的解决方案将是复杂的,甚至可能会减慢您的查询速度,直到您获得该数据量。

编辑:哦,是的,加入反对那些100k +桌子的时间不到一秒钟。只是对你的一些看法...

答案 3 :(得分:0)

我真的不认为数万行会成为数据库查找的问题。我建议在第二种方法中使用第一种方法。

答案 4 :(得分:0)

  

我想从这个池中随机选择一个图像并显示它   对用户,但我想确保这个用户从未见过   这张图片之前。

对于它的价值,这不是随机算法;这是一个随机算法。 (当你需要更多关于它的细节时,知道这将使谷歌更容易。)但这不是你最大的问题。

  

所以我在想:当用户观看图像时,我会排成一行   在MYSQL中插入,表示“此用户已观看此图像   (时间)“为每个条目。

好的想法。使用存储用户已经看到特定图像的事实的表在您的情况下是有意义的。除非我错过了什么,否则你不需要存储时间。 (你可能不应该。它似乎没有任何有用的商业目的。)这些方面的东西应该运作良好。

-- Predicate: User identified by [user_id] has seen image identified by
-- [image_filename] at least once.
create table images_seen (
  user_id integer not null references users (user_id),
  image_filename not null references images (image_filename),
  primary key (user_id, image_filename)
);

测试并查看EXPLAIN的输出。如果您需要image_filename上的二级索引。 。

create index images_seen_img_filename on images_seen (image_filename);

这仍然不是你最大的问题。

最大的问题是你自己没有测试过。如果您知道任何脚本语言,那么您应该能够在几分钟内生成10,000行进行测试。如果你这样做了,你会发现这样的表即使有数百万行也能表现良好。

在回答StackOverlow上的问题之前,我有时会生成数百万行来测试我的想法。

学习生成大量随机(ish)数据进行测试是数据库和应用程序开发人员的基本技能。