0

我有一个包含主要症状,额外症状和疾病的数据库。我需要替换2个查询,因为我确定我的第一个查询效率不高,而我的第二个查询不是正确的。我希望有人能帮助我,因为我是新来这个领域..MySQL查询获取所有(额外)症状和疾病

数据库解释:

数据库正在使用由医疗应用:

  1. 用户选择特定的身体部位
  2. 该应用程序列出了具体的身体部分的所有主要症状
  3. 用户选择一个主要症状(公共或较少)
  4. 该应用程序列出了所选主要症状的所有疾病。还会出现2个复选框(附加症状),可以由用户检查。列出的疾病顺序(d_weight)取决于年龄,性别,选定的主要症状以及用户检查了哪些方框。认为是d_weight < = 5的疾病是常见疾病。 d_weight> 5的疾病被认为不太常见。用户输入(年龄,性别,身体部位,主要症状)的可能性存储在symptom_disease_combi表中。

    • asa_id是应用(即由用户检查addtional症状)
    • asc_id是的属于特定的主要症状,其他症状所有可能性的ID的所有症状的ID。例如,如果没有选择其他症状,则asc_id = 0。 asc_id = 1,如果只选择其他症状“失眠”。 asc_id = 2,以防止'失眠'和'爆炸'被选中。

1.查询以获得一个特定的身体部分的所有症状(可以改善):

SELECT DISTINCT s.name 
       , s.id 
       , sdc.s_common 
      FROM symptom as s 
       , symptom_disease_combi as sdc 
      WHERE sdc.age = ".$age." 
      AND sdc.gender = ".$gender." 
      AND sdc.bodypart = ".$bodypart." 
      AND sdc.s_id = s.id 

2.查询来获取所有的疾病和选择的症状的其它症状(不工作):

SELECT DISTINCT d.name 
       , d.id 
       , sdc.d_weight 
       , adls.id 
       , adls.name 
      FROM disease as d 
       , symptom_disease_combi as sdc 
       , symptom as s 
       , adlsymptom as adls 
      WHERE sdc.age = ".$age." 
      AND sdc.gender = ".$gender." 
      AND sdc.bodypart = ".$bodypart." 
      AND s.id = ".$sid." 
      AND sdc.s_id = s.id 

3。数据库结构(请让我知道,如果我的设计可以提高)

CREATE TABLE symptom 
(id INT NOT NULL AUTO INCREMENT 
,name VARCHAR(100) DEFAULT NULL 
,critical INT NOT NULL 
,PRIMARY KEY (id) 
) ENGINE=MyISAM; 

id name     critical 
1 Behavioral disturbances  1 
2 Ear pressure     0 
3 Elevated temperature   0 
4 Fainting      0 
5 Head pain      0 

CREATE TABLE disease (
id int(11) NOT NULL AUTO_INCREMENT, 
name varchar(100) DEFAULT NULL, 
critical int(11) NOT NULL, 
description text NOT NULL, 
tests text NOT NULL, 
treatment text NOT NULL, 
PRIMARY KEY (id) 
) ENGINE=MyISAM AUTO_INCREMENT=19 DEFAULT CHARSET=latin1 

id name    critical description tests  treatment 
1 Adjustment disorder 0   lorem ipsum lorem ipsum lorem ipsum 
2 ADHD    0   lorem ipsum lorem ipsum lorem ipsum 
3 Drug reaction  0   lorem ipsum lorem ipsum lorem ipsum 
4 Seizure (epilepsy) 1   lorem ipsum lorem ipsum lorem ipsum   

CREATE TABLE adlsymptom (
id int(11) NOT NULL AUTO_INCREMENT, 
name varchar(100) NOT NULL, 
PRIMARY KEY (id) 
) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 

id name 
1 Insomnia 
2 Blowing up 
3 Depressed 
4 Drug abuse 

CREATE TABLE adlsymptom_apply (
id int(11) NOT NULL, 
as_id int(11) NOT NULL, 
PRIMARY KEY (id,as_id), 
KEY FK_additional_symptom_that_apply (as_id) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

id as_id 
1 1 
1 2 

CREATE TABLE adlsymptom_combi (
id int(11) NOT NULL, 
as_id int(11) NOT NULL, 
PRIMARY KEY (id,as_id), 
KEY FK_additional_symptom_combination (as_id) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 

id as_id 
1 1 
2 2 
3 1 
3 2 

CREATE TABLE symptom_disease_combi (
id int(11) NOT NULL AUTO_INCREMENT, 
age int(11) NOT NULL, 
gender int(11) NOT NULL, 
bodypart int(11) NOT NULL, 
s_id int(11) NOT NULL, 
s_common int(11) NOT NULL, 
asc_id int(11) NOT NULL, 
asa_id int(11) NOT NULL, 
d_id int(11) NOT NULL, 
d_weight int(11) NOT NULL, 
PRIMARY KEY (id), 
KEY FK_symptom (s_id), 
KEY FK_additional_symptom_combination (asc_id), 
KEY FK_additional_symptom_that_apply (asa_id), 
KEY FK_disease (d_id) 
) ENGINE=MyISAM AUTO_INCREMENT=65 DEFAULT CHARSET=latin1 

id age gender bodypart s_id s_common asc_id asa_id d_id d_weight 
1 1 1  1  1 1  0  1  1 1 
2 1 1  1  1 1  0  1  2 2 
3 1 1  1  1 1  0  1  3 3 
4 1 1  1  1 1  0  1  11 4 

更新1:

  • 疾病critical和病征创建告诉他们需要去用户医院立即当他们点击疾病或症状时
  • age,gender,bodypart是id的,所以age = 1,意味着0-5,age = 2表示6-17,age = 3表示18-59和age = 4表示60+。
  • 请看看应用程序的设计,这将有助于了解数据库的设计:http://i.imgur.com/p9QP1av.png btw,在设计中;导致==疾病...
  • asa_id指adlsymptom_apply
  • asc_id ID referst到adlsymptom_combi
  • 的 '独特' 的ID是用来获取所有症状/疾病仅仅1次。我相信这不是必需的,但我不知道如何解决它。
+0

那么问题是什么?你在找什么?你有最终产出的样本吗?另外,请用你的表格和一些示例数据创建小提琴 –

+1

请学习使用明确的'join'语法。一个简单的规则:在'from'子句中不要使用逗号。 –

+0

将症状分成两个表的意义如何?这可能会在2张桌子上连续流鼻涕?并且保持第二个交叉表,使联接复杂化,并且降低性能 – AsConfused

回答

1

沟2症状表,有一个(症状)和1个交叉表(SDC)去

我会添加一个新列的症状,如状态/水平试图抬高一症状 重要的主要或次要的,尽管诱惑,因为这可能很容易 使它不灵活。

例如,昏厥似乎主要用于一次疾病/病症,但它可以在普通

扭曲它去的通用性,因此1表症状,你正确地在SDC一个d_weight

我喜欢你的sdc.d_weight概念。例如,昏厥可能对癫痫有一定的影响,但对流感不起作用。整个概念 拧当有人与流感规定Zarontin而不是达菲

,因为我喜欢你的sdc.d_weight概念,我不知道为什么你的其他症状表

表SDC

去了,你具有名称以“FK_”开头的键/索引。希望你已经实际FK constrainst

,而不只是命名约定,让你觉得你有他们(FK的,你没有他们)

例如,真正的FK对身体部位,症状和疾病/病症。

当用户选择的症状,从GUI的再次添加该症状搜索

能力删除此减少了工作和开沟辅助表简化查询(的我写的1号线和建议)

音符,再次,你的KEY的使用(这是指数,而不是外键约束的代名词),只是创建 指数...

create table symptom 
(
    id int not null auto_increment primary key, 
    name varchar(100) not null, -- if you can't put a name to it, don't have it 
    critical int not null 
)ENGINE=MyISAM default charset=latin1; 

create table disease 
(
    id int not null auto_increment primary key, -- don't mix and match int with int(11) 
    name varchar(100) not null, -- if you can't put a name to it, don't have it 
    critical int not null, 
    -- etc columns, text 
)ENGINE=MyISAM default charset=latin1; 

create table symptom_disease_combi 
( -- a.k.a. sdc 
    id int not null auto_increment primary key, -- don't mix and match int with int(11) 
    age int not null, 
    gender char(1) not null, -- int(11) is overkill 
    bodypart int not null, 
    s_id int not null, 
    s_common int not null, 
    asc_id int not null, 
    asa_id int not null, 
    d_id int not null, 
    d_weight int not null, 

    -- additional indexes (note pk above, so it is there and happy) 

    -- note that some of your indexes (your KEYS) are worthless for the queries in question 
    -- however they may be useful for other queries in your system 
    -- for instance your asc and asa indexes will not be useful as they won't be picked up 
    -- in relation to the question posed 
    -- 
    -- you will need to find the proper balance of index bloat based on system needs 

    INDEX idx_sdc_siddid (s_id,d_id,bodypart), -- composite, general purpose 
    INDEX idx_sdc_didsid (d_id,s_id,bodypart), -- ditto but reverse 
    INDEX idx_sdc_ascid (asc_id), 
    INDEX idx_sdc_asaid (asa_id), 
    -- put constraints here: 
    CONSTRAINT `fk_sdc_bodypart` FOREIGN KEY (bodypart) REFERENCES bodypart(id), 
    CONSTRAINT `fk_sdc_sid` FOREIGN KEY (s_id) REFERENCES symptom(id), -- don't mix and match int and int(11) 
    CONSTRAINT `fk_sdc_did` FOREIGN KEY (d_id) REFERENCES disease(id) 
    -- are there others, such as asc asa tables ?? 
)ENGINE=MyISAM default charset=latin1; 

我认为你需要漫长而艰难的思考年龄列 被SDC将被装入一个新的行,每个年龄,50〜120,性别=“M”,为匍匐癌症? 我基于你的年龄= xxxxx行,也许你的意思是> =。或为白血病,< = ...我认为 您的架构需要一点思想

的,所以我不包括从下面的查询

年龄 - 在接下来的查询,我不知道为什么你需要一个不同? - 对于给定症状行是否有多于1个sdc.s_common?只有您自己知道 - 如果不是,沟明显

- 你的加入对条款事项的顺序,使其遵循一个很好的指标,以便结果回来快

- 我并不认为这些是覆盖指标,但你将尽量减少表扫描活动

select distinct s.name, s.id, sdc.s_common 
from symptom s 
join symptom_disease_combi sdc 
on sdc.s_id=s.id and sdc.bodypart=".$bodypart." and sdc.gender= ".$gender." 

- 不是我的上述有关 年龄评论 - 需要在计算列

那些是我的建议合并的权重,祝你好运

+0

非常感谢你的回答,但是我看到还有些东西没有足够清晰的解释,所以我会更新我的帖子。关于你的问题的一些额外信息... – Engo