Лучший способ передать большое количество значений в запросе SQL? - PullRequest
0 голосов
/ 06 июля 2019

Я создаю приложение для iOS, которое использует функцию считывания / сопоставления, похожую на трут. У меня есть база данных MySQL, которая используется для сопоставления пользователей с людьми, которые соответствуют критериям поиска пользователя. Swiping feature

Функция смахивания. ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ My users' search criteria Критерии поиска моего пользователя. What my table base of users looks like Как будет выглядеть моя таблица пользователей.

Я создал конечную точку API с использованием php и SQL для обновления информации о каждом пользователе при внесении изменений и получения всех соседних пользователей, которые соответствуют критериям поиска пользователя.

Вот как выглядит php для поиска ближайших пользователей.

$uid        = strval($_GET['uid']);
$lat        = floatval($_GET['lat']);
$lng        = floatval($_GET['lng']);
$minAge     = intval($_GET['minAge']);
$maxAge     = intval($_GET['maxAge']);
$gender     = intval($_GET['gender']);
$radius     = intval($_GET['radius']);
$type       = intval($_GET['type']);

// This SQL statement selects users from the table 'users' so long as 
//they are within x miles of the user's location and within the age 
//range and gender requirements

$sql = "SELECT *,
    (((acos(sin((?*pi()/180)) * sin((`lat`*pi()/180))+cos((?*pi()/180)) * cos((`lat`*pi()/180)) * cos(((?- `lng`)*pi()/180))))*180/pi())*60*1.1515)
    AS distance
    from users having distance<? AND gender=? AND age<? AND age>? AND type=? AND uid<>?"; 

//Bind parameters to the placeholders
mysqli_stmt_bind_param($stmt, "dddiiiiis", $lat, $lat, $lng, $radius, $gender, $maxAge, $minAge, $type, $uid);

//Run parameters inside database
mysqli_stmt_execute($stmt);

И URL-адрес для выполнения этого запроса может выглядеть примерно так:

https://mywebsitename.com/getNearbyUsers.php?uid=4pW2I1gpq5VHCHEdm0aEfTRgJO92&lat=38.461822509765625&lng=-90.32567239374883&minAge=18&maxAge=100&gender=2&radius=50&type=3

Мой выпуск:

Теперь, когда пользователь (пользователь1) проводит пальцем вправо или влево по другому пользователю (пользователь2), я хочу отслеживать, что этот пользователь2 уже был представлен пользователю1, чтобы они не были представлены в будущем.

Что я изначально планировал сделать:

Моей первой мыслью, чтобы решить эту проблему, было создание еще одного столбца в моей базе данных SQL, который, по сути, представлял бы собой массив uids, сообщающий, какие пользователи уже были показаны текущему пользователю. Всякий раз, когда пользователь во внешнем интерфейсе (user1) проводит пальцем вправо или влево, профиль другого пользователя user1 (user2) user2 может быть добавлен в массив пользователей, к которым уже применен user1. Затем в выражении SQL я мог бы сказать, что нужно возвращать только тех пользователей, которых нет в столбце uids текущего пользователя "readyPresentedWith".

Проблема: Я исследовал ссылки на большие наборы значений в SQL и обнаружил, что в реляционной базе данных не должно быть более одного значения на столбец. Однако, учитывая мои навыки и опыт, это единственный способ, который я могу себе представить, выполняя эту задачу.

Мне бы очень хотелось получить отзывы от более опытных разработчиков php / SQL о том, в каком направлении мне лучше всего идти для решения такого рода проблем.

1 Ответ

2 голосов
/ 06 июля 2019

У вас должна быть таблица, скажем swipes, с одной строкой для каждого действия.Скажите:

create table swipes (
    swipes_id int auto_increment primary key,
    swiper_uid binary(16),
    swipee_uid binary(16),
    action varchar(5),  -- 'left', 'right', 'none'
    created_at datetime default now(),
    foreign key (swiper_uid) references persons(uid),
    foreign key (swipee_uid) references persons(uid)
);

Редактировать из OP Итак, решение было простым.Я сделал таблицу смахиваний, как было предложено, создал конечную точку API, которая вставляет «смахивание» в таблицу каждый раз, когда происходит смахивание (в моем случае нам не нужно хранить, смахнул ли пользователь влево или вправо), а затем обновилОператор SQL в моей конечной точке, который получает соседних пользователей.

My 'swipes' table

В операторе SQL я добавил проверку NOT EXISTS для ссылки на таблицу смахивания и проверкуесли запись имеет текущего пользователя как «swiper» и пользователь, возвращенный запросом как «swipee».Вот как выглядит подготовленный оператор в php-файле, который получает ближайший пользователь.

$sql = "SELECT *,
(((acos(sin((?*pi()/180)) * sin((`lat`*pi()/180))+cos((?*pi()/180)) * cos((`lat`*pi()/180)) * cos(((?- `lng`)*pi()/180))))*180/pi())*60*1.1515)
AS distance
from users having distance<? AND gender=? AND age<? AND age>? AND type=? AND uid<>? AND NOT EXISTS(SELECT NULL
                FROM swipes s
               WHERE s.swiperUid=? AND u.uid=s.swipeeUid)"; 

//Bind parameters to the placeholders
mysqli_stmt_bind_param($stmt, "dddiiiiiss", $lat, $lat, $lng, $radius, $gender, $maxAge, $minAge, $type, $uid, $uid);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...