假设我需要一个名为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