2016-12-13 169 views
0

假設我需要一個名爲skills的字段,它應該存儲一個人的各種技能,如php,java,Golang搜索包含多個值的字段

什麼是適當的方法來在數據庫中存儲這些數據,以便使其由技能更容易

編輯1

用戶可以輸入任何他想要的技能搜索,上面只是一個例子

用戶可以在文本框中鍵入一個或多個技能,用逗號

分離實施例

skill1,skill2,skill3 
+0

也許你可以提供你的**編輯1 **的含義的例子。 – gmiley

+0

不明白爲什麼這是downvoted!這是使用'SET'列的情況的一個很好的例子。 – cFreed

回答

0

什麼是適當的方式存儲在 數據庫,數據

你應該有一個單獨的表叫Skills,所有的技能應該存在,它也應該有一個FOREIGN KEY引用父表PRIMARY KEY字段。

這樣,在需要的時候可以JOIN與父表和GROUP BY父表鍵字段,並得到所有相關的技能

2

你或許應該重新審視自己的設計方法(如果要列出所有技能GROUP_CONCAT())和將這些技能存儲在名爲skills的相關表中,其中列skill_idskill_nameskill_desc等...然後使用交叉參考表來鏈接您的人員表中的person_idskills表中的skill_id

如果無法執行的重新設計,你可以使用查詢的一系列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語句:

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; 

,將讓你所有的技能與@personIDperson_id的人。

或者你也可以與特定skill_id用下面的查詢選擇所有在people表的人:

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結尾的任何內容,例如mysqlpl/sql,或只是sql

+0

檢查編輯...用戶可以輸入任何技能,所以我不知道技能事先 – user2650277

+0

我不知道如何改變我的建議。通過'people_skills_xref'表,通過'people'與'skills'之間的M:M關係,您可以將任意數量的技能以任意組合方式應用於任意數量的人員。另外你不會重複你的技能。 「技能」表中只需要一個條目。 – 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應該提供相同的功能。

重要提示:我認爲這是唯一給你所需要的強大,因爲一些你不明確你的任擇議定書表示方法,但可能是一個要求:給定的人可能有幾個技能

2日重要提示:OP的編輯狀態

用戶可以輸入任何他想要的技能

這是唯一的地步SET不起作用直接根據需要,因爲不同的可能值必須在列定義級別註冊(但顯然可以更新以進化)。
因此,如果用戶想要提及一些當前未知的技能,則必須向他提供一種「聲明」這種新技能的註冊方法,然後將其註冊在定義列中,並實際更新用戶skills字段。

+0

聲稱的方法似乎很棒... ... stackoverflow風格:) – user2650277

+0

@ user2650277作爲一個非母語英語的演講者,我不知道我的話是怎麼回事:從您的評論我猜我沒有選擇正確的方式來表達.. 。我也很快寫了這個答案,所以它有點縮寫。我所說的「聲稱」是:用戶應該有一個建議的(註冊)技能列表,他將從哪裏選擇他想要的內容。而這個列表應該包含諸如'other'之類的東西,當它被選擇時會導致輸入區域輸入新技能。然後,您的後端腳本應該檢測到這種情況並相應地進行處理(在更新表之前修改列表)。 – cFreed

+0

我完全理解你的意思。我想說的是,stackoverflow也使用你提到的建議系統 – user2650277