#php #mysql #database #select #csv
#php #mysql #База данных #выберите #csv
Вопрос:
Я работаю над разработкой системы «друзей» для своего сайта. В моей базе данных есть таблица ПОЛЬЗОВАТЕЛЕЙ и два поля в этой таблице, которые называются «friendrequestssent» и «friendrequestsreceived».
Когда пользователь отправляет запрос на добавление в друзья другому пользователю, он сохраняет его идентификатор пользователя в поле «friendrequestsreceived» другого человека, а идентификатор пользователя другого человека — в поле «friendrequestssent», оба с завершающей запятой (т.Е.: 12345,
).
Мне нужно проверить, существует ли уже запрос, чтобы предотвратить дублирование запросов, и до сих пор я пробовал это:
$sql = "SELECT * FROM users WHERE userid = $userid AND $profileid IN (friendrequestssent);";
$sent = mysql_num_rows(mysql_query($sql));
$sql = "SELECT * FROM users WHERE userid = $profileid AND $userid IN (friendrequestsreceived);";
$received = mysql_num_rows(mysql_query($sql));
if(($sent > 0) amp;amp; ($received > 0)) {
//do stuff here
}
Сначала это работало отлично, но когда в поле существует несколько значений, разделенных запятыми (т. Е.: 12345,12346,
), Оператор IN больше не находит значение, и количество строк остается равным нулю.
Насколько я могу судить, я не понимаю, почему оператор IN в запросе MySQL не увидит значение.
С другой стороны, я уверен, что в любом случае есть гораздо лучший способ сделать это. Я просто пока не уверен, как это сделать. Пожалуйста, сообщите.
Комментарии:
1. CSV в базе данных — это зло, оно отправит вас прямо в ад.
2. Не зависит от типа IN()? т.Е. Вы не смешиваете целые числа и строки и фактически передаете целое число (идентификатор пользователя) в строку (csv) — возможно, все в порядке только с одной записью, если нет запятой, она может быть в состоянии оценить строку чиселкак int. Я не уверен на 100%, хотя я никогда не использую CSV в базе данных — они просто кричат мне: «Это должна быть таблица ссылок»…
Ответ №1:
Предложение IN просматривает отдельные элементы списка, разделенного запятыми, но когда вы сохраняете этот список, разделенный запятыми, в одном поле, MySQL обрабатывает его как однострочное значение, поэтому вы делаете
... WHERE x IN ('1,2,3')
что переводится в
... WHERE x = '1,2,3'
Чтобы заставить MySQL обрабатывать этот список CSV как CSV, а не монолитную строку, вам понадобится FIND_IN_SET()
функция:
... WHERE FIND_IN_SET($profileid, friendrequestssent);
Комментарии:
1. Хотя создание отдельной таблицы для запросов на добавление в друзья было гораздо более эффективным решением, ваш ответ по-прежнему полезен на случай, если мне когда-нибудь понадобится использовать что-то подобное
IN
снова, и я уверен, что так и сделаю. Спасибо.
Ответ №2:
Не обрабатывайте одно поле так, как будто оно состоит из нескольких строк. Для этого используйте таблицу. Что-то вроде:
friend_requests
===============
friend_id
requested_friend_id
friend_id
и requested_friend_id
будет содержать составной ключ.
Ответ №3:
Ваш дизайн в порядке, но будет лучше, если вы позволите мне переделать это для вас:
Сначала оставьте свою таблицу users как есть, затем создайте новую таблицу с 3 полями:
- Поле автоинкремента в качестве вашего индекса (если вы этого хотите, или просто пропустите этот столбец).
- Поле, в котором вы храните друга, который запрашивает дружбу и позволяет вызывать: friend_request .
- Поле, в котором вы сохраняете друга, который получает запрос на дружбу, и позволяет вызвать ir: friend_receive_request .
Вы должны добавить индексы внешнего ключа propper и помнить, что у вас могут быть повторяющиеся запросы, сохраняя одни и те же данные в разных столбцах. Я мог бы уточнить это подробнее, если у вас есть вопросы.
Комментарии:
1. Ах, да, я вижу, как отдельная таблица для запросов на добавление в друзья может быть более эффективной. Я произвел некоторую перенастройку, и она работает замечательно. Спасибо!
Ответ №4:
одна вещь, которую вы можете сделать, это извлечь всю запись, содержащую все идентификаторы в виде массива или строки, и соответствующим образом определить поиск по строке или поиск по массиву, чтобы проверить дублирование.