Как сохранить, а затем выполнить поиск по CSV в sql?

#mysql #arrays #csv

#mysql #массивы #csv

Вопрос:

Я знаю, что могу использовать IN (1,2,3) для выбора элементов из базы данных SQL, где их значение равно 1, 2 или 3, но что, если у меня есть значение в MYSQL, которое является строкой и равно ‘1,2,3’, и я хочу выбрать это значение. Насколько я знаю, я должен это сделать:

 SELECT whatever FROM wherever WHERE sqlvariable = '1' OR sqlvariable LIKE '1,%' OR `sqlvariable` LIKE '%,1,%' OR `sqlvariable` LIKE '%,1'
  

это нормально, если я хочу имитировать ‘IN’ как бы наоборот. Но допустим, я хочу выбрать sqlvariable, где он содержит либо 1, либо 2, тогда я должен сделать это:

 SELECT whatever FROM wherever WHERE sqlvariable = '1' OR sqlvariable LIKE '1,%' OR `sqlvariable` LIKE '%,1,%' OR `sqlvariable` LIKE '%,1' OR sqlvariable = '2' OR sqlvariable LIKE '2,%' OR `sqlvariable` LIKE '%,2,%' OR `sqlvariable` LIKE '%,2'
  

Теперь предположим, что я использую PHP для генерации вышеуказанных запросов, и я ищу sqlvariable, где он содержит 1 2 4 66 34 33 22 44 или 992. Выполнение этого запроса займет ужасно много времени.

Я мог бы выполнить побитовую реализацию, но тогда я ограничен наличием всего около 60 различных элементов или около того, чего недостаточно.

Есть ли более быстрый способ использовать CSV-запрос, подобный приведенному выше, в sql? Я полагаю, это что-то вроде IN (), но наоборот.

Комментарии:

1. Я, конечно, надеюсь, что вы на самом деле не храните строки CSV в своей базе данных SQL! И если это так, я надеюсь, вы сможете убедить своего босса или администратора базы данных быть немного умнее и проанализировать csv-файл, прежде чем сохранять его.

2. У меня нет начальника, я просто канадец, пытающийся учиться, сэр: P Спасибо за ваши комментарии, я действительно пытаюсь изучить лучший подход к хранению массивов в базах данных. Я знаю, что на форумах vBulletin информация о группе разрешений хранится, например, в виде строки CSV. Например, переменная разрешений на форуме vbulletin выглядит как ‘1,2,3’, где каждое число представляет другую группу разрешений. Как это лучше сделать?

Ответ №1:

Вы можете упростить свои запросы, используя FIND_IN_SET :

 SELECT whatever
FROM   wherever
WHERE  FIND_IN_SET('1', sqlvariable)
OR     FIND_IN_SET('2', sqlvariable)
  

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


Обновление: Ваш существующий дизайн выглядит примерно так:

 groupname   groupmembers
Group1      1,2,3
Group2      3,4
  

Вы должны изменить это на что-то более похожее на это:

 groupid   groupmember
1         1
1         2
1         3
2         3
2         4
  

Комментарии:

1. Спасибо! Как я мог бы изменить дизайн моей таблицы. У меня есть таблица, которая группирует пользователей в разные группы пользователей. Для хранения списка пользователей, которые принадлежат к группе пользователей, прямо сейчас у меня есть таблица с двумя значениями: ‘groupname’, ‘groupmembers’. Поскольку иногда в groupmembers может быть более 100 пользователей, я не уверен, как их сохранить, кроме как используя CSV и имея что-то вроде ‘1,2,3,4,5,6’ в качестве значения для groupmembers, где каждое число представляет пользователя.