2013-10-04 113 views
-1

我有幾個表:MySQL的大型關係型查詢

letter_mail

index 
sent  
from  
to 
template  
public 
stamp 
stationery 
title 
content  
opened 

letter_user

index 
username  
password 

在letter_mail所有行的關係,除了指數,公共並打開了另一張桌子。

from和to在letter_mail中對應於letter_user的索引。我想要的是從數據庫中提取所有數據,如果可能,最好在一個查詢中提取。 A *選擇上letter_mail一行將產生多少這樣的結果:

index:1  
sent: 2013-10-03  
from:1 
to:2  
template:1 
public:1  
stamp:1  
stationery:1  
title: 1  
content: 1 
opened : 0 

我需要什麼,是上述從相關表填充數據的信息,並JSON編碼。看起來有點像這樣:

index:1  
sent: 2013-10-03  
from: {1, John}  
to: {2, Jane} 
template: {index: 1, template: "standard template", url: "template_name"} 
public: 0  
stamp: {index: 1, stamp: "standard stamp", url: "some/url"}  
stationery: {index: 1, stamp: "standard stationery", url: "some/url"}  
title: {index: 1, title: "some title"}  
content: {index: 1, content: "some text content"}  
opened : 0 

這是完全瘋了嗎?我應該把查詢分解成幾個比特還是將所有內容整理到一張表中?

select 
    mail.index, 
    mail.sent, 
    mail.opened, 
    mail.public, 
    FromU.username as FromUser, 
    ToU.username as ToUser, 
    T.template as TemplateName, 
    T.url as TemplateURL, 
    S.stamp, 
    S.url as StampURL, 
    S.stamp Stamp, 
    STA.url StationaryURL, 
    Ttl.title, 
    C.content 
from 
    letter_mail mail 
    JOIN letter_user FromU 
     on mail.from = FromU.index 
    JOIN letter_user ToU 
     on mail.to = ToU.index 
    JOIN letter_templates T 
     on mail.template = T.index 
    JOIN letter_stamps S 
     on mail.stamp = S.index 
    JOIN letter_stationery STA 
     on mail.stationery = STA.index 
    JOIN letter_title Ttl 
     on mail.title = Ttl.index 
    JOIN letter_content C 
     on mail.content = C.index 

的查詢工作,但不會返回任何行:

,如果您需要了解更多信息:)

溶液在該請告訴。

+0

並不瘋狂 - 儘管最終會有大量的重複數據在單個查詢中同時獲得。這是否是一個好主意取決於數據的數量以及從Web服務器到數據庫的接近度/連接。 – Orbling

+0

我只是想避免有9個選擇查詢,但如果這是需要的話......是的。我可以將查詢中的所有數據存儲在主表中,但這在查詢一件事情時也會產生開銷。 此外,如果人們downvote,請告訴爲什麼:) – Eirinn

+0

是不是我 - 有些人只是記下他們認爲基本的任何問題。除非應該將所有數據放在一張表中,否則應避免數據重複,並且是關係數據庫的主要觀點。您應該只需要兩個查詢,但每個表只有一個查詢。鏈接可以用PHP完成。 – Orbling

回答

2

正如dmcnelis指出的那樣,您可以考慮使用連接(比舊的ANSI格式的列表更多的當前語法和應用WHERE標準)。這裏是他使用JOIN語法的版本..我也修改了在表上使用更短的別名引用。注意,JOIN/ON顯示了tableX與tableY的關係,而不是隱藏在WHERE子句中。這有時會導致問題和笛卡爾結果,如果你有OOPS忘記了where子句。通過加入,你會立即看到你的關係標準。

select 
     L.sent, 
     FromU.username as FromUser, 
     ToU.username as ToUser, 
     T.name as TemplateName, 
     T.url as TemplateURL, 
     L.public, 
     S.stamp, 
     S.url as StampURL, 
     STA.stamp StationaryStamp, 
     STA.url StationaryURL, 
     title.title, 
     C.content, 
     L.opened 
    from 
     letter_mail L 
     JOIN letter_user FromU 
      on L.from = FromU.index 
     JOIN letter_user ToU 
      on L.to = ToU.index 
     JOIN template T 
      on L.Template = T.index 
     JOIN stamp S 
      on L.Stamp = S.index 
     JOIN stationary STA 
      on L.Stationary = STA.index 
     JOIN title 
      on L.title = title.index 
     JOIN content C 
      on L.Content = C.index 

既然所有的表都是相關的,那麼運行查詢就可以得到所需的一切。但是,如果你正在尋找的東西的一組特定的標準,則只需添加一個WHERE子句中......諸如

WHERE 
     L.From = 27 
    OR L.To = 27 

得到任何電子郵件或用戶27

如果你只是想具體的固定,郵票,標題等,只是根據需要添加。

+0

它有意義嗎?或者我應該重組數據庫? – Eirinn

+1

我看到你的事情已經崩潰了沒有什麼不妥......在數據庫中有很多查找表是很常見的。想一想,如果你有100,000條記錄,並且必須重複固定式「標準固定式」而不是內部ID 8,那麼你是否選擇了拼寫?修復查找表,你就完成了。你的環境看起來很好。 – DRapp

+0

它的工作原理!謝謝!我已經用你的答案更新了這個問題,並獎勵了通過upvotes導致這個答案的任何人。 – Eirinn

1

總之,您可以使用表別名來多次加入同一個表。我做了一對夫婦的其他相關表名的假設,但本質上你會最終有一個查詢看起來像這樣:

select 
    sent, from.username, to.username, template_table.name, template_table.url, public, 
    stamp_table.stamp, stamp_table.url, stationary_table.stamp, stationary_table.url, title_table.title, 
    content_table.content, opened 
from 
    letter_mail l, 
    letter_user from, 
    letter_user to, 
    template template_table, 
    stamp stamp_table, 
    stationairy stationary_table, 
    title title_table, 
    content content_table 
where 
    l.from = from.idex 
    and l.to = to.index 
    and template = template_table.index 
    and stamp = stamp_table.index 
    and stationairy = stationary_table.index 
    and title = title_table.index 
    and content = content_table.index 
    where l.index = X 

你會遇到的主要問題是,這將導致多次掃描letter_user表......這可能是可以避免的,但是應該記住,如果這個數據庫具有任何實際重要的大小。

做這樣的查詢,而不是整理多個數據庫調用的好處是,你讓數據庫做它設計的工作,並且只對數據庫進行一次調用。

當然這種查詢可以重新工作了一點專門使用加入...但對我來說,這種形式更易於閱讀和理解,假設你只需要嚴格的相關記錄。