Как мне отфильтровать массив php с таблицей MySQL? - PullRequest
4 голосов
/ 21 октября 2008

Скажем, у меня есть массив строк в массиве php с именем $ foo с несколькими сотнями записей, и у меня есть таблица MySQL 'people', в которой есть поле с именем 'name' с несколькими тысячами записей. Какой эффективный способ узнать, какие строки в $ foo не являются «именем» в записи в «людях», не отправляя запрос для каждой строки в $ foo?

Итак, я хочу выяснить, какие строки в $ foo еще не были введены в 'people.'

Обратите внимание, что очевидно, что все данные должны быть в одном окне в одной точке. Целью было бы сделать это одновременно с минимизацией количества запросов и объема обработки php.

Ответы [ 7 ]

1 голос
/ 21 октября 2008

Лучшее, что я могу придумать, не используя временную таблицу:

 $list = join(",", $foo);

// fetch all rows of the result of 
// "SELECT name FROM people WHERE name IN($list)" 
// into an array $result

$missing_names = array_diff($foo, $result);

Обратите внимание, что если $ foo содержит пользовательский ввод, его сначала нужно экранировать.

1 голос
/ 21 октября 2008

А как насчет следующего:

  1. Получить список имен, которые уже есть в БД, используя что-то вроде: SELECT name FROM people WHERE name IN (imploded list of names)
  2. Вставьте каждый элемент из возврата array_diff()

Если вы хотите сделать это полностью в SQL:

  1. Создать временную таблицу с каждым именем в массиве PHP.
  2. Выполните запрос для заполнения второй временной таблицы, которая будет содержать только новые имена.
  3. Сделайте INSERT ... SELECT из второй временной таблицы в таблицу людей.

Ни один из них не будет ужасно быстрым, хотя второй вариант может быть немного быстрее.

1 голос
/ 21 октября 2008

Я бы поместил ваши данные $ foo в другую таблицу и сделал бы ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ с таблицей имен В противном случае, не так много хороших способов сделать это, которые не требуют итерации в какой-то момент.

0 голосов
/ 21 октября 2008
CREATE TEMPORARY TABLE PhpArray (name varchar(50));

-- you can probably do this more efficiently
INSERT INTO PhpArray VALUES ($foo[0]), ($foo[1]), ...;

SELECT People.*
FROM People
 LEFT OUTER JOIN PhpArray USING (name)
WHERE PhpArray.name IS NULL;
0 голосов
/ 21 октября 2008
$query = 'SELECT name FROM table WHERE name != '.implode(' OR name != '. $foo);

Да, это не похоже, что оно будет хорошо масштабироваться.

0 голосов
/ 21 октября 2008

Для нескольких сотен записей просто используйте array_diff () или array_diff_assoc ()

0 голосов
/ 21 октября 2008

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

По сути, есть два варианта: получить список всех строк в MySQL и перенести их в PHP и выполнить сравнения, или отправить список всех строк на сервер MySQL и позволить ему выполнять сравнения. MySQL сделает сравнения намного быстрее, чем PHP, если только список в базе данных не намного меньше, чем список в PHP.

Вы можете создать временную таблицу, но в любом случае перенести все данные в базу данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...