2011-08-15 56 views
2

我有一個託管的在線商店產品,它支持各種數據類型的自定義字段。切正題,任何人都可以通過向表中添加額外的鍵/值對任何記錄被定義爲:在MySQL中使用子查詢進行語言環境回退

`storeId` varchar(20) NOT NULL, 
`locale` varchar(100) NOT NULL, 
`table` varchar(30) NOT NULL, 
`id` varchar(50) NOT NULL, 
`key` varchar(30) NOT NULL, 
`value` mediumblob NOT NULL, 
PRIMARY KEY (`storeId`, `locale`, `table`, `id`, `key`) 

在歐洲,很多人要支持多國語言,所以每個鍵可以有不同地區的多個值。每個商店將具有默認區域設置(由店主指定)和活動區域設置(由客戶選擇)。

我想放在一起查詢的行爲就像這樣:

  • storeIdtableid都是已知的,是積極的語言環境和默認語言環境。
  • 如果某個鍵的值對於活動語言環境不可用,則會返回默認語言環境的值。
  • 如果默認語言環境的值也不可用,請返回任意其他語言環境的值。

我想出了一個非常尷尬的查詢,達到了預期的結果。假設商店ID是1,表格是Products,ID是gadget1;默認語言環境爲en_AU,活動語言環境爲de_DE。以下是我們要查詢的內容:

SELECT * FROM 
    (SELECT `key`, `value` 
    FROM nf_CustomFields 
    WHERE `storeId` = 1 
     AND `table` = 'Products' 
     AND `id` = 'gadget1' 
    ORDER BY `locale`='de_DE' DESC, 
     `locale`='en_AU' DESC 
    ) 
AS a 
GROUP BY `key`; 

這樣做很有效,但它很醜,看起來效率不高。我知道還有更好的辦法,但我不能把手指放在上面。

有人可以提出更好的建議嗎?

非常感謝!

+0

我在過去做過類似的事情。儘管我設置它有點不同:每個事物都有它的原始/默認語言,然後是一組翻譯。這樣你就沒有第三種選擇,不管他們是他們的語言還是他們獲得了該項目的母語。 OTOH,'en_AU'確實在英國有一定的吸引力:) –

+0

好吧,結果證明我所做的就是要做最好的事情。好吧。一個人可以做夢。 –

回答

1

您可以嘗試使用LEFT JOINing​​本身,然後使用COALESCE忽略LEFT JOIN在沒有本地語言行時會產生的NULL。事情是這樣的(未經測試,可能無法正常工作)查詢:

select coalesce(nl.`key`, def.`key`), 
     coalesce(nl.`value`, def.`value`) 
from nf_CustomFields nl 
left outer join nfCustomFields def 
    on nl.`store` = def.`store` 
    and nl.`table` = def.`table` 
    and nl.`id`  = def.`id` 
    and nl.`locale` = 'de_DE' 
where def.`locale` = 'en_AU' 
    and def.`id`  = KNOWN 
    and def.`store` = KNOWN 
    and def.`table` = KNOWN 

KNOWN當然會,與您已知值取代,你會取代'de_DE'當然'en_AU'使用真正的動態值。

+0

有趣的想法。我會給它一個旋風,但我不確定它是否允許計劃C(回退到任何可用的語言環境)。乾杯! –

+0

@尼爾:我敢肯定,你可以擴展這種方法,以允許「任何可用的語言」的東西。另一個LEFT JOIN,重新調整連接條件和WHERE,並向COALESCE調用添加另一列。它不會很漂亮,但它應該可以正常工作並且可以通過適當的索引來執行。 –

+0

謝謝隊友。我會做一些基準測試並回復你:) –

相關問題