У меня есть конечная точка API, которая возвращает X количество случайных сообщений из таблицы, называемой «сообщения». Эта конечная точка используется мобильным приложением. Он получает случайные сообщения, выполнив SELECT COUNT (*) в таблице сообщений и вернув количество сообщений в таблице. Затем он входит в цикл for, в котором в начале каждого цикла генерируется случайное число от 0 до COUNT (*). Случайный пост затем получается с помощью удобного смещения. Этот цикл продолжается до тех пор, пока не будет получено X случайных сообщений.
псевдокод:
FUNCTION getRandPosts :
$numOfPosts = queryExecute("SELECT COUNT(*) from posts");
for (iterations < numOfRandomPostsNeeded) {
$randomNumber = rand(0, $numOfPosts)
$randomPost = queryExecute("SELECT * from posts LIMIT 1, OFFSET $randomNumber")
}
Теперь для каждого вызова функции getRandPosts я хочу, чтобы они всегда извлекали уникальную запись, которая не была получена ранее. Для этого текущего вызова getRandPosts И ДЛЯ ПРОШЛЫХ ВЫЗОВОВ.
Я думал о нескольких способах сделать это:
Я мог бы хранить идентификаторы уже увиденных постов в массиве в приложении, а затем отправить этот массив в функцию getRandPosts. Затем функция getRandPosts использует предложение NOT IN.
FUNCTION getRandPosts(ARRAY $idsOfPostsAlreadySeen) :
...
for ...
$randomPost = queryExecute("SELECT * from posts
WHERE id NOT IN $idsOfPostsAlreadySeen
LIMIT 1, OFFSET $randomNumber")
$idsOfPostsAlreadySeen.addToArray($randomPost.id)
...
После получения каждой случайной записи сохраните этот идентификатор записи в таблице с именем «seenPosts», где также имеется столбец с именем idOfApp, который используется для различения пользователей.
FUNCTION getRandPosts(STRING appInstallID) :
...
for ...
$randomPost = queryExecute("SELECT posts.* FROM posts
JOIN seenPosts.postID FROM seenPosts
ON posts.id = seenPosts.postID
WHERE seenPosts.postID = null AND seenPosts.appInstallID = $appInstallID
LIMIT 1, OFFSET $randomNumber")
queryExecute("INSERT INTO seenPosts SET postID = $randomPost.id, appInstallID = $appInstallID")
...
Я также хотел бы спросить об идее, для идеи номер один, создать временную таблицу из массива и использовать JOIN с этой временной таблицей по сравнению с использованием массива.
Рассмотрим идею о том, что не более 600 сообщений должны быть исключены для любого данного пользователя (так что в случае первой идеи это массив из 600 идентификаторов).
Задача ещё не решена.
Других решений пока нет …