2016-12-13 3 views
0

Предположим, мне нужно поле под названием skills в моей таблице. Оно должно хранить различные навыки человека, такие как php, java, Golang.Поиск поля, содержащего несколько значений

Что бы соответствующий подход для хранения таких данных в базе данных, так что это сделать поиск по навыку легче

Edit 1

Пользователь может ввести все, что он хочет для навыков, выше просто пример

пользователь может ввести один или несколько навыков в текстовом поле, разделенных запятыми

Пример

skill1,skill2,skill3 
+0

Возможно, вы могли бы привести пример того, что вы подразумеваете под своим ** Редактированием 1 **. – gmiley

+0

Не понимаю, почему это было приостановлено! Это довольно хорошая иллюстрация, где можно использовать столбцы «SET». – cFreed

ответ

0

Что бы соответствующий подход для хранения таких данных в базе данных

Вы должны иметь отдельную таблицу под названием Skills, где все навыки должны присутствовать, и он должен также иметь FOREIGN KEY ссылаясь на родительскую таблицу PRIMARY KEY.

Так что, в случае необходимости вы можете JOIN с родительской таблицы и GROUP BY поле ключа родительской таблицы (GROUP_CONCAT(), если вы хотите, чтобы перечислить все навыки) и получить все связанные с ними навыки

2

Вы, вероятно, следует пересмотреть свой подход к проектированию и сохраните эти навыки в связанной таблице skills с колонками skill_id и skill_name и skill_desc и т. д. ... затем используйте таблицу перекрестных ссылок, чтобы связать person_id с вашей таблицей людей, а также skill_id из таблицы skills.

Если вы не можете выполнить редизайн, вы можете использовать запрос с серией LIKE звонков:

SELECT * 
FROM people 
WHERE skills LIKE '%php%' 
    OR skills LIKE '%java%' 
    OR skills LIKE '%Golang%'; 

Но это довольно неряшливо. Я бы пошел с редизайном. Использование LIKE будет отрицать любое преимущество индексов.

Чтобы развернуть несколько таблиц выше, когда пользователь вводит список разделенных запятыми навыков, вам необходимо проанализировать это в коллекции/массиве, проверить их присутствие в новой таблице skills. Если он не существует, вы его вставляете. Затем, или если он существует, вы потянете skill_id и вставьте его в таблицу person_skills_xref с помощью person_id (если эта комбинация еще не существует).

Таким образом, вы можете сделать отборное заявление вроде:

SELECT s.skill_id, s.skill_name, s.skill_desc 
FROM skills s 
JOIN people_skills_xref ps 
ON s.skill_id = ps.skill_id 
WHERE ps.person_id = @personID; 

Это поможет вам все навыки для человека с person_id из @personID.

Или вы можете выбрать все люди в people таблицы с определенным skill_id с помощью следующего запроса:

SELECT p.person_id, p.person_name, p.person_email 
FROM people p 
JOIN people_skills_xref ps 
ON ps.person_id = p.person_id 
WHERE ps.skill_id = @skillId; 

Или skill_name с помощью LIKE:

SELECT p.person_id, p.person_name, p.person_email 
FROM people p 
JOIN people_skills_xref ps 
ON ps.person_id = p.person_id 
JOIN skills s 
ON s.skill_id = ps.skill_id 
WHERE s.skill_name LIKE @skillName; 

Где @skillName будет содержать строку поиска '%sql', чтобы соответствовать чему-либо, оканчивающемуся sql, например mysql, pl/sql или просто sql.

+0

check edit ... пользователь может ввести что-либо для навыков, поэтому я не знаю навыков заранее – user2650277

+0

Я не уверен, как это изменит то, что я рекомендовал. С отношением M: M от 'people' to' skills' через таблицу 'people_skills_xref' вы можете использовать любое количество навыков для любого количества людей в любой комбинации. Кроме того, вы не будете дублировать свои навыки. В таблице 'skills' потребуется только одна запись. – gmiley

1

Вы должны использовать 3 таблицы:

User 
----------------- 
id 
name 

Skill 
----------------- 
id 
name 

User_Skill 
----------------- 
user_id 
skill_id 

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

Если вы хотите получить все навыки пользователя вы можете использовать:

select s.* from Skills s left join User_Skills us on us.skill_id = s.id where us.user_id = <insert user id>; 
+0

[_Optimal Many: Many table schema_] (http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table). –

1

IMO более простой (и легко использовать, в то же время) путь для того, что вам нужно, чтобы использовать уникальный столбец типа SET.

Основные резюме, как это работает:

  • определение поля: что-то вроде skills SET('php','java','goLang',...)

  • Заполнение поля (с одним или несколькими навыками сразу): UPDATE table SET skills = 'php, java'

  • ищут данный навык: SELECT * FROM table WHERE FIND_IN_SET('java', skills) > 0

Посмотрите на это MySQL page, предполагая, что MariaDB должен предлагать те же возможности.

ВАЖНО: Я думаю, что это только метод дает Вам нужен мощный, из-за того, что вы четко не говорил в ОП, но, вероятно, является требование: данное лицо может иметь несколько навыки !

второй ВАЖНОЕ ПРИМЕЧАНИЕ: Op отредактируем состояния

Пользователь может ввести все, что он хочет для навыков

Это единственная точка, где SET не работает непосредственно по мере необходимости, так как различные возможные значения должны быть зарегистрированы на уровне определения столбца (но, очевидно, могут быть обновлены для развития).
Так что, если пользователь хочет упомянуть о незнакомом в настоящее время навыке, вы должны предложить ему способ «потребовать», чтобы этот новый навык был зарегистрирован, затем зарегистрируйте его в столбце определения и фактически обновите поле пользователя skills.

+0

претензия в отношении метода кажется потрясающей ... stackoverflow style :) – user2650277

+0

@ user2650277 Как неродный английский динамик Я не знаю, как звучат мои слова: из вашего комментария я думаю, что я не выбрал правильный способ выразить. Я также написал этот ответ довольно быстро, поэтому он несколько сокращен. То, что я имею в виду с «требованием», заключается в следующем: пользователь должен иметь предлагаемый список (зарегистрированных) навыков, откуда он выберет то, что хочет. И этот список должен включать нечто вроде 'other ', которое при выборе приводит к области ввода, где нужно ввести новый навык. Затем ваш фоновый скрипт должен обнаружить этот случай и обработать его соответствующим образом (модифицируя команду def def перед обновлением таблицы). – cFreed

+0

Я понимаю, что вы имеете в виду. Я хотел сказать, что stackoverflow также использует систему предложений, на которую вы ссылаетесь – user2650277

Смежные вопросы