SQL查询优化

吻科潘尼

我的ch_skills桌子看起来像

uid | skill1 | skill2 | skill3 | skill4 | skill5
1     1        2        2        0        1
2     1        1        2        1        1
3     1        2        3        0        1

我的第一个问题:这是正确的吗?我的意思是,如果这样做的话会更好:

uid | skillid | skill_lvl
1     1         1
1     2         2
1     3         2
1     4         0
1     5         1

到现在为止,示例1一切正常,但是现在我在sql查询方面遇到了麻烦。目前,我正在使用5个不同的查询来获取每种技能的水平。我使用以下代码:

对于技能1:

$query = $this->db->prepare("SELECT `skills`.`skill_ID` as `Skill1_id`, 
   `skill_name`.`skill_name` as `Skill1_name`, `skill_level` as `Skill1_level`, 
   `skill_price` as `Skill1_price` 
   FROM `skills`, `skill_name`, `ch_skills` 
   WHERE `skill_name`.`skill_ID` = `skills`.`skill_ID` 
   AND `skills`.`skill_ID`= 1 
   AND `skills`.`skill_level` = `ch_skills`.`skill1`
   AND `ch_skills`.`uid` = :uid");

对于Skill2:

$query = $this->db->prepare("SELECT `skills`.`skill_ID` as `Skill1_id`, 
   `skill_name`.`skill_name` as `Skill1_name`, `skill_level` as `Skill1_level`, 
   `skill_price` as `Skill1_price` 
   FROM `skills`, `skill_name`, `ch_skills` 
   WHERE `skill_name`.`skill_ID` = `skills`.`skill_ID` 
   AND `skills`.`skill_ID`= 2 
   AND `skills`.`skill_level` = `ch_skills`.`skill2`
   AND `ch_skills`.`uid` = :uid");

依此类推...正如您所看到的,只有两个区别:skill_id = 2和skill2作为同名的名字。有什么方法可以只查询1个查询中的全部5个技能吗?还是您还是建议我更改表结构?

注意:skills代表技能价格和skill_name技能名称。

史考特

正如其他评论者所建议的那样,最好的选择是完全按照您的建议更改表格。

没有第一个示例中所示的宽表的最大原因是,增加技能意味着更改数据库的结构,这可能会破坏现有的查询。

其次,正如您所看到的,当您尝试查询结果时,只有一个表并没有使它更容易使用。

对于像您的示例这样的非标准化表,唯一可能的好处是它占用的磁盘空间略少。但是在当今世界,磁盘空间永远不应该成为您的主要关注点。

但是,要回答有关查询原始非规范化示例的问题,有两种方法可以解决:

  1. 使用union语句,它将5个不同的查询组合在一起。这是非常低效的
  2. 创建一个具有5行(在这种情况下)的表(或者,如果您有Skills表,则使用该表)。然后将ch_skills表加入该表,该表应该占据每一行并将其拆分5次。参见下文:(注意:在本示例中,我假设Skill和skill_name的关系为1:1,并且每个仅有5条记录)

    选择skillsskill_IDskill_nameskill_nameskill_levelas Skill_levelskill_priceSkill_priceFROM skillsJOINskill_name有关skill_nameskill_ID= skillsskill_IDch_skills哪里加入ch_skillsuid=:uid AND((skills。。skill_ID1 AND skillsskill_level= ch_skillsskill1)OR(skillsskill_ID= 2 AND skillsskill_level= ch_skillsskill2)OR(skillsskill_ID= 3 AND skillsskill_level= ch_skillsskill3)OR(skillsskill_ID= 4 AND skillsskill_level= ch_skillsskill4)OR(skillsskill_ID= 5 AND skillsskill_level= ch_skillsskill5))

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章