Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 数据库表设计与查询_Php_Mysql_Sql_Database_Select - Fatal编程技术网

Php 数据库表设计与查询

Php 数据库表设计与查询,php,mysql,sql,database,select,Php,Mysql,Sql,Database,Select,我正在开发一个php程序,用户需要从下拉列表中选择skillsone或更多 然后我将结果保存在数组中: 用户技能[] 然后每个项目都有一个所需技能的列表,我将它保存在另一个数组中:proj_skills[] 问题是: 将这些信息保存到数据库中的最佳方式是什么 我应该创建两个新表吗?一个用于项目技能和用户技能列:proj_id和skill 每一项技能都是连续的 将项目与用户技能进行比较并找到匹配技能的最佳方法是什么? 从用户技能中选择id,其中技能=项目技能[i],从用户技能中选择id,其中技能=

我正在开发一个php程序,用户需要从下拉列表中选择skillsone或更多 然后我将结果保存在数组中: 用户技能[] 然后每个项目都有一个所需技能的列表,我将它保存在另一个数组中:proj_skills[]

问题是: 将这些信息保存到数据库中的最佳方式是什么 我应该创建两个新表吗?一个用于项目技能和用户技能列:proj_id和skill 每一项技能都是连续的

将项目与用户技能进行比较并找到匹配技能的最佳方法是什么? 从用户技能中选择id,其中技能=项目技能[i],从用户技能中选择id,其中技能=项目技能[i+1]。。。。。。。嵌套选择/循环或递归

如何做到这一点,最佳和优化的方法是什么


希望清楚,提前感谢:

如果一个用户可以与多个项目关联,并且一个项目可以与多个用户关联,那么听起来最好将用户和项目的技能存储在单独的表中

在设置了两个表之后,我将创建第三个表来保存所有可能的技能我假设没有任何技能只能与用户或项目关联。现在您将拥有以下表格、用户、项目、用户技能和项目技能

一旦这些都设置好了,并且假设您可以将UserID和ProjectID传递到查询中,我就将用户技能与SkillID上的项目技能结合起来。例如:

SELECT Q1.UserID,
       Q1.Skill
FROM   (SELECT Users.UserID,
               Skills1.Skill,
               Skills1.SkillID
        FROM   Users
               INNER JOIN UserSkills
                 ON Users.UserID = UserSkills.UserID
               INNER JOIN Skills AS Skills1
                 ON UserSkills.SkillID = Skills1.SkillID
        WHERE  Users.UserID = 123) AS Q1
       INNER JOIN (SELECT Projects.ProjectID,
                          Skills2.Skill,
                          Skills2.SkillID
                   FROM   Projects
                          INNER JOIN ProjectSkills
                            ON Projects.ProjectID = ProjectSkills.ProjectID
                          INNER JOIN Skills AS Skills2
                            ON Project.SkillID = Skills2.SkillID
                   WHERE  ProjectID = 456) AS Q2
         ON Q1.SkillID = Q2.SkillID;

通常,在使用SQL时,您希望避免迭代。你最好的表现是只要求一次你想要的东西。另外,如果您以上面所写的方式进行迭代,您将假设所有ID都是按顺序排列的,但是这些技能可能不会按顺序排列。因此,这两种技能可能有共同点1和3,但不是2。在技能2没有任何共同点后,你会停止你的循环吗?你必须分头思考。另外,要注意IN子句。如果您试图测试某个内容是否不在包含null的结果集中,则即使您是用户和项目具有共同的技能,也不会收到任何结果。这里有一篇关于这个主题的文章

我不是一个php程序员,所以你的一些问题我不知道,但是在数据库设计方面,你需要三个表:人员、技能和技能。后一个表将是“链接表”,至少有两个字段作为联合主键:人员和技能。你可以把这个人掌握技能的程度加到这个表上

如果您有一个项目表和另一个项目所需所有技能的链接表,那么为了找到具备该项目所需技能的人员,您需要编写如下内容:

select people.name, skills.name
from people inner join skillsperperson on people.id = skillsperperson.person
inner join skills on skillsperperson.skill = skills.id
inner join skillsperproject on skills.id = skillsperproject.skill
where skillsperproject = :p1;  

:p1是传递给查询的参数;它的值将是给定项目的id。

我不知道这是最好的还是最优化的方法,但这里有一种方法:

首先,您需要的表:为了简单起见,我省略了名称列等

CREATE TABLE skills (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
) ENGINE=InnoDB;

CREATE TABLE users (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
) ENGINE=InnoDB;

CREATE TABLE projects (
    id INT UNSIGNED NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (id)
) ENGINE=InnoDB;

CREATE TABLE user_skills (
    user_id INT UNSIGNED NOT NULL,
    skill_id INT UNSIGNED NOT NULL,
    PRIMARY KEY (user_id, skill_id),
    FOREIGN KEY (user_id) REFERENCES users (id),
    FOREIGN KEY (skill_id) REFERENCES skills (id)
) ENGINE=InnoDB;

CREATE TABLE project_skills (
    project_id INT UNSIGNED NOT NULL,
    skill_id INT UNSIGNED NOT NULL,
    PRIMARY KEY (project_id, skill_id),
    FOREIGN KEY (project_id) REFERENCES projects (id),
    FOREIGN KEY (skill_id) REFERENCES skills (id)
) ENGINE=InnoDB;
如果要显示至少具有编号为1、3和5的技能的所有用户:

SELECT user_id
FROM user_skills
WHERE skill_id IN (1, 3, 5)
GROUP BY user_id
HAVING COUNT(*) = 3;
所以在这里,我们首先用where子句过滤掉所有不相关的技能,然后按用户分组。之后,COUNT*告诉我们每个用户有多少匹配技能。having子句只显示具有3项匹配技能的用户,这意味着这些用户至少拥有我们所寻找的技能

如果要显示具有技能1、3和5但没有其他技能的所有用户:

SELECT s1.user_id
FROM (
    SELECT user_id, COUNT(*) count
    FROM user_skills
    GROUP BY user_id
) s1
INNER JOIN (
    SELECT user_id, COUNT(*) count
    FROM user_skills
    WHERE skill_id IN (1, 3, 5)
    GROUP BY user_id
) s2 ON (s1.user_id = s2.user_id)
WHERE s1.count = 3 AND s2.count = 3;
这里,第一个子查询查找每个用户的总技能数,第二个子查询查找每个用户的匹配技能数。如果两者都是3,则用户完全具备我们所需要的技能

如果要查找所有兼容的用户和项目,即用户至少具备项目所需的所有技能的所有项目、用户对:

SELECT s2.project_id, s2.user_id
FROM (
    SELECT project_id, COUNT(*) count
    FROM project_skills
    GROUP BY project_id
) s1
INNER JOIN (
    SELECT project_skills.project_id, user_skills.user_id, COUNT(*) count
    FROM project_skills
    INNER JOIN user_skills ON (user_skills.skill_id = project_skills.skill_id)
    GROUP BY project_skills.project_id, user_skills.user_id
) s2 ON (s1.project_id = s2.project_id)
WHERE s2.count = s1.count;
在这里,第一个子查询找出每个项目所需的技能数量。第二个子查询找出每个项目有多少通用技能,即用户对。它通过在技能上加入项目技能和用户技能,然后按项目和用户分组来实现这一点。然后,COUNT*告诉每个项目和用户有多少通用技能。最后,我们加入两个子查询,只显示项目、用户对,其中常见技能的数量等于项目需要的技能数量