Когда использовать значения через запятую в столбце БД? - PullRequest
0 голосов
/ 22 сентября 2011

ОК, я знаю, что технический ответ: НИКОГДА .

НО, бывают случаи, когда кажется, что все намного проще с меньшим количеством кода и, по-видимому, несколькими недостатками, поэтому, пожалуйста, здесьme out.

Мне нужно создать таблицу с именем Restrictions, чтобы отслеживать, с каким типом пользователей хотят связаться, и которая будет содержать следующие 3 столбца (для простоты):

minAge
lookingFor
drugs

lookingFor и drugs могут содержать несколько значений.

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

Но кажется, что использование значений через запятую значительно упрощает реализацию и выполнение.Вот пример:

Допустим, Пользователь 1 имеет следующие ограничения:

minAge => 18
lookingFor => 'Hang Out','Friendship'
drugs => 'Marijuana','Acid'

Теперь, скажем, Пользователь 2 хочет связаться с Пользователь 1 .Ну, во-первых, нам нужно посмотреть, соответствует ли он ограничениям User 1 , но это достаточно просто ДАЖЕ С разделенными запятыми столбцами, например:

Сначала я получу цель( Пользователь 1 ) Ограничения:

SELECT * FROM Restrictions WHERE UserID = 1

Теперь я просто помещаю их в соответствующие переменные как есть в PHP:

$targetMinAge = $row['minAge'];
$targetLookingFor = $row['lookingFor'];
$targetDrugs = $row['drugs'];

Теперь мы просто проверяем, соответствует ли ОТПРАВИТЕЛЬ ( Пользователь 2 ) этому простому критерию:

COUNT (*) 
   FROM Users
WHERE 
   Users.UserID = 2 AND
   Users.minAge >= $targetMinAge AND
   Users.lookingFor IN ($targetLookingFor) AND
   Users.drugs IN ($targetDrugs)

Наконец, если COUNT == 1, Пользователь 2 может связаться с Пользователь 1 , иначе они не могут.

Насколько просто было ТО ?Это просто кажется действительно простым и понятным, так в чем же РЕАЛЬНАЯ проблема с этим, если я очищаю все входные данные в БД каждый раз, когда пользователь обновляет свои ограничения на контакты?Возможность использовать функцию MySQL IN и уже хранить несколько значений в понятном им формате (например, значения через запятую) кажется намного проще, чем создавать таблицы соединений для каждого столбца с множественным выбором.И я привел упрощенный пример, но что, если есть 10 столбцов с множественным выбором?Тогда с такими множествами объединяющихся таблиц дела идут не так, как надо, в то время как метод CSV остается простым.

Так что, в этом случае действительно ТАК плохо, если я использую значения, разделенные запятыми?

**** утки ****

Ответы [ 2 ]

7 голосов
/ 22 сентября 2011

Вы уже знаете ответ.

Во-первых, ваш PHP-код даже близко не работает, потому что он работает, только если у пользователя 2 есть только одно значение в LookingFor или Drugs.Если какой-либо из этих столбцов содержит несколько значений, разделенных запятыми, IN не будет работать , даже если эти значения находятся в том же порядке, что и значения пользователя 1.Что ожидать от IN, если справа имеет одну или несколько запятых?

Поэтому в PHP не так-то просто сделать то, что вы хотите.На самом деле это довольно сложно, и это потребовало бы разделения полей пользователя 2 на отдельные значения, написания динамического SQL со многими OR для выполнения сравнения, а затем выполнения крайне неэффективного запроса для получения результатов.вам даже нужно написать код PHP , чтобы ответить на такой относительно простой вопрос о пересечении двух множеств, что означает, что ваш дизайн имеет серьезные недостатки.Это именно такая проблема (реляционная алгебра), которую существует для решения SQL.Правильный дизайн позволяет решить проблему в базе данных , а затем просто внедрить верхний слой представления в PHP или какой-либо другой технологии.

Сделайте это правильно, и у вас будет многопроще время.

1 голос
/ 22 сентября 2011

Предположим, что пользователь 1 ищет слова "Hangout", "Friendship", а пользователь 2 ищет слова "Friendship", "Hangout"

Ваш код не будет совпадать с ними, потому что «Friendship», «Hang Out» не включены («Hang Out», «Friendship»)

Это настоящая проблема здесь.

...