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