MySQL:如何确保始终选择唯一记录

时间:2017-09-19 06:53:25

标签: python mysql

我正在运行一个产生多个进程的Python脚本。该进程调用一个方法,该方法每次针对特定条件运行SELECT查询并获取N条记录。我面临的问题是每个进程几乎同时生成,SELECT同时执行,因此许多进程针对SELECTs获取相同的记录

我想知道是否有办法选择独特的记录?我知道Order by Rand(),但这看起来很昂贵。

下面给出的表格式:

+-------------+--------------+------+-----+-------------------+----------------+
| Field       | Type         | Null | Key | Default           | Extra          |
+-------------+--------------+------+-----+-------------------+----------------+
| id          | int(11)      | NO   | PRI | NULL              | auto_increment |
| url         | varchar(255) | NO   | MUL | NULL              |                |
| source_file | varchar(255) | NO   |     |                   |                |
| proxy_url   | varchar(255) | NO   |     | NULL              |                |
| duration    | int(11)      | NO   |     | NULL              |                |
| status      | int(11)      | NO   | MUL | NULL              |                |
| updated_at  | datetime     | YES  |     | CURRENT_TIMESTAMP |                |
+-------------+--------------+------+-----+-------------------+----------------+

由于

1 个答案:

答案 0 :(得分:0)

必须在执行SELECT之前或返回结果集之后在应用程序级别完成。在选择之前我肯定会选择。假设有5个进程生成,每个进程返回10行的结果集。您可以创建5个10个数字的列表,并将其传递给每个进程。这是我将如何做到这一点。 (这假定主键是顺序的,从0开始,并且没有从表中删除任何记录的情况):

首先,主脚本执行查询以获取表中记录的计数。假设这返回10000.我会做这样的事情:

from random import shuffle

process_count = 5
need = 10
list_of_lists = []

values = list(range(10000))
shuffle(values)

for i in range(process_count):
    start = i * need
    m = values[start:start+10]
    list_of_lists.append(m)

或者你可以绕过循环并使用列表理解:

list_of_lists = [ values[i*need:i*need+10] for i in range(process_count)]

list_of_lists现在包含5个列表,其中包含0和表大小之间的10个有效随机数。此时,迭代list_of_lists并将列表输出到生成的进程。在每个生成的进程中,该列表用于从TABLE生成SELECT,其中ID为IN()语句。

+++++++++++编辑++++++++++++++++++

定期删除记录的事实会带来一些问题。首先,您不能简单地对表进行计数,因为由于存在间隙,因此max id将大于表计数。您可以简单地返回所有id值,随机播放它们,并创建单个列表。随着表格变大,这可能是昂贵且不切实际的。  你可以通过发送一个类似这样的初始查询来解决这个问题:

select max(id) from <tablename>;

然后您可以生成如下列表:

values = list(range(max_id_value + 1))

此时您可以这样做:假设您需要从每个衍生进程返回10行。如果您发送每个10个数字的列表,如果发送的数字与ID不对应,则进程将发送少于10个。解决此问题的一种方法是向每个进程发送30个值的列表。然后在select查询中你可以添加LIMIT 10.你发送的数字将取决于id列表的稀疏程度。

希望这是有道理的