2014-12-26 112 views
0

形勢SQL /(Django的):對於翻譯

我試圖建立一個數據庫模式來存儲轉換,不同語言之間的有效數據庫模式。到目前爲止,它看起來像這樣(簡單):

class Language(models.Model): 
    tag = models.CharField(max_length=2) 

    def __unicode__(self): 
     return self.tag 

class Phrase(models.Model): 
    name = models.TextField() 
    language = models.ForeignKey(Language) 

    def __unicode__(self): 
     return self.name 

    class Meta: 
     unique_together = ("name", "language") 
     index_together = [ 
      ["name", "language"] 
     ] 

class Translation(models.Model): 
    phrase1 = models.ForeignKey(Phrase, related_name="translation_as_1") 
    phrase2 = models.ForeignKey(Phrase, related_name="translation_as_2") 

    def __unicode__(self): 
     return self.phrase1.name + " <=> " + self.phrase2.name 

    class Meta: 
     unique_together = ("phrase1", "phrase2") 
     index_together = [ 
      ["phrase1", "phrase2"] 
     ] 

這個數據庫模式似乎對我來說合乎邏輯。我用不同語言存儲短語,然後翻譯包含兩個短語。

問題

的問題是,查詢,導致了這個模式的,看起來有種討厭。例如:

from django.db.models import Q 

name = "my phrase" 
translations = Translation.objects.filter(Q(phrase1__name=text)|Q(phrase2__name=text)) 
translated_names = [] 
for translation in translations: 
    name1 = translation.phrase1.name 
    name2 = translation.phrase2.name 
    if name1 == name: 
     translated_names.append(name2) 
    else: 
     translated_names.append(name1) 

我總是要包含「或」的關係,以確保,我得到的所有可能的翻譯,因爲這句話可以存儲爲phrase1或phrase2。最重要的是,我必須過濾我的結果才能得到正確的compiled_name(for循環)。

進一步闡釋

之前,我切換到所描述的模式,我有以下模式,而不是(PhraseLanguage都和以前一樣):

class Translation(models.Model): 
    phrase = models.ForeignKey(Phrase) 
    name = models.TextField() 

    def __unicode__(self): 
     return self.phrase.name + " => " + self.name 

    class Meta: 
     unique_together = ("phrase", "name") 
     index_together = [ 
      ["phrase", "name"] 

這種模式讓我查詢像這樣:

from django.db.models import Q 

name = "my phrase" 
translations = Translation.objects.filter(phrase__name=text) 
translated_names = [t.name for t in translations] 

這看起來好多了,當然是更快。但是這種模式有一個缺點,它只向一個方向提供翻譯,所以我轉移到了另一個,這並不是我想要的,因爲查詢太慢而且太複雜。

問題

那麼,有沒有一個好的模式對於這類問題,我也許忽略?

備註

我不是隻關心Django的相關答案。針對這種問題的純SQL模式對我來說也很有趣。

回答

0

這是我過去做過的。適應你的命名習慣。

假設我有一個名稱的表和其他列像這樣

TR_CLT_clothing_type現在

clt_id | clt_name | other columns .... 
-------------------------------------- 
1  | T Shirt ... 
2  | Pants ... 

,如果我決定了它需要的翻譯,首先我做一個語言表

TR_LNG_language

lng_id | lng_name | lng_display 
------------------------------- 
1  | English | English (NZ) 
2  | German | Deutsch 

我還需要將當前語言存儲在數據庫中(您將會看到爲什麼會很快)。它只會有一排

TA_INF_info

inf_current_lng 
--------------- 
1 

然後我從我的衣服表TR_CLT_clothing_typeclt_name列。相反,我做關係表。

TL_CLT_clothing_type

clt_id | lng_id | clt_name 
-------------------------- 
1  | 1  | T Shirt 
1  | 2  | (German for T-Shirt) 
2  | 1  | Pants 
2  | 2  | keuchen (thank you google translate) 

我們得到名字,你想一個存儲過程吧。我沒有嘗試過ORM。

CREATE PROCEDURE PS_CLT 
    @clt_id int 
AS 

SELECT lng.clt_name, clt.* 
FROM TR_CLT_clothing_type clt 
JOIN TL_CLT_clothing_type lng 
ON lng.clt_id = clt.clt_id 
WHERE clt.clt_id = @clt_id AND 
     lng.lng_id in (SELECT inf_current_lng FROM TA_INF_info) 

該存儲過程將返回當前語言的名稱和指定語言的所有其他列。要設置語言,請在TA_INF_info表中設置clt_current_lng

聲明:我沒有任何東西來檢查我輸入的語法,但它應該很簡單。

- 編輯

有是能夠做到「給我一個字X在語言Y語言Z,它們的翻譯」

有一個「不那麼優雅」的方式關注對模式執行此操作。你可以這樣做

for each table in database like "TL_%" 

    SELECT name 
    FROM table 
    WHERE id IN ( SELECT id 
      FROM table 
      WHERE name = @name 
      AND lng_id = german 
      ) 
    AND lng_id = english 

現在我可以想象,這將需要一些自動生成的SQL代碼,但我可以把它關閉。

我不知道你會如何做到這一點在ORM

+0

感謝您的回答。但是你的建議方式非常之多,我之前有過並在「進一步解釋」一節中描述過。它的缺點是,我無法通過兩種方式存儲翻譯。最後,我希望能夠以下列方式簡單高效地查詢翻譯:「給我所有的Y語言的X字翻譯爲Z語言的翻譯」 – basilikum