假設我需要一個名爲skills
的字段,它應該存儲一個人的各種技能,如php
,java
,Golang
。搜索包含多個值的字段
什麼是適當的方法來在數據庫中存儲這些數據,以便使其由技能更容易
編輯1
用戶可以輸入任何他想要的技能搜索,上面只是一個例子
用戶可以在文本框中鍵入一個或多個技能,用逗號
分離實施例
skill1,skill2,skill3
假設我需要一個名爲skills
的字段,它應該存儲一個人的各種技能,如php
,java
,Golang
。搜索包含多個值的字段
什麼是適當的方法來在數據庫中存儲這些數據,以便使其由技能更容易
編輯1
用戶可以輸入任何他想要的技能搜索,上面只是一個例子
用戶可以在文本框中鍵入一個或多個技能,用逗號
分離實施例
skill1,skill2,skill3
什麼是適當的方式存儲在 數據庫,數據
你應該有一個單獨的表叫Skills
,所有的技能應該存在,它也應該有一個FOREIGN KEY
引用父表PRIMARY KEY
字段。
這樣,在需要的時候可以JOIN
與父表和GROUP BY
父表鍵字段,並得到所有相關的技能
你或許應該重新審視自己的設計方法(如果要列出所有技能GROUP_CONCAT()
)和將這些技能存儲在名爲skills
的相關表中,其中列skill_id
和skill_name
和skill_desc
等...然後使用交叉參考表來鏈接您的人員表中的person_id
和skills
表中的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;
,將讓你所有的技能與@personID
的person_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
結尾的任何內容,例如mysql
,pl/sql
,或只是sql
。
檢查編輯...用戶可以輸入任何技能,所以我不知道技能事先 – user2650277
我不知道如何改變我的建議。通過'people_skills_xref'表,通過'people'與'skills'之間的M:M關係,您可以將任意數量的技能以任意組合方式應用於任意數量的人員。另外你不會重複你的技能。 「技能」表中只需要一個條目。 – gmiley
你應該使用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>;
[_Optimal Many:Many table schema_](http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table)。 –
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
字段。
聲稱的方法似乎很棒... ... stackoverflow風格:) – user2650277
@ user2650277作爲一個非母語英語的演講者,我不知道我的話是怎麼回事:從您的評論我猜我沒有選擇正確的方式來表達.. 。我也很快寫了這個答案,所以它有點縮寫。我所說的「聲稱」是:用戶應該有一個建議的(註冊)技能列表,他將從哪裏選擇他想要的內容。而這個列表應該包含諸如'other'之類的東西,當它被選擇時會導致輸入區域輸入新技能。然後,您的後端腳本應該檢測到這種情況並相應地進行處理(在更新表之前修改列表)。 – cFreed
我完全理解你的意思。我想說的是,stackoverflow也使用你提到的建議系統 – user2650277
也許你可以提供你的**編輯1 **的含義的例子。 – gmiley
不明白爲什麼這是downvoted!這是使用'SET'列的情況的一個很好的例子。 – cFreed