Как мне проверить, существует ли значение в поле, разделенном запятыми?

#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:

одна вещь, которую вы можете сделать, это извлечь всю запись, содержащую все идентификаторы в виде массива или строки, и соответствующим образом определить поиск по строке или поиск по массиву, чтобы проверить дублирование.