Database
 sql >> Baza danych >  >> RDS >> Database

Jak zaprojektować system gotowy do lokalizacji

W dobie globalizacji firmy – w tym twórcy oprogramowania – są zawsze zainteresowane ekspansją na nowe rynki. Często oznacza to lokalizację ich produktów w różnych obszarach. W tym artykule wyjaśnimy kilka podejść do projektowania modelu danych pod kątem lokalizacji – w szczególności do zarządzania treścią w wielu językach.

Co to jest lokalizacja?

Lokalizacja to proces dostosowywania produktu do różnych rynków. Jest to ważny czynnik w osiągnięciu maksymalnego udziału w rynku pod względem sprzedaży produktów. Gdy lokalizacja zostanie wykonana prawidłowo, użytkownicy poczują, że produkt został stworzony dla ich języka, kultury i potrzeb.

W miejscach, w których angielski nie jest powszechnym językiem ojczystym, ankiety wykazały, że języki lokalne są preferowane dla oprogramowania. Ten artykuł MediaPost zawiera kilka interesujących danych dotyczących zapotrzebowania na języki inne niż angielski, jeśli chodzi o sprzedaż międzynarodową.

Co możesz stracić, jeśli nie lokalizujesz?

Rozważmy niefortunny przykład braku lokalizacji. Dla wygody klientów portal e-commerce umożliwił klientom łączenie pojedynczych zakupów w cztery grupy. Niestety wymowa słowa „cztery” w języku japońskim brzmi jak ich słowo oznaczające „śmierć”. Japończycy zazwyczaj unikają wszystkich rzeczy związanych z tą liczbą, ponieważ uważa się ją za pechową. Nie trzeba dodawać, że sprzedaż tych produktów nie szła dobrze na rynku japońskim.

Tak więc, odpowiadając na powyższe pytanie, możesz dużo stracić, jeśli nie zaplanujesz dokładnie swojego rynku docelowego.

Tłumaczenie treści jako lokalizacja

Kiedy myślimy o lokalizacji, tłumaczenie treści to często pierwsza myśl, jaka przychodzi nam do głowy. Druga myśl brzmi:„Potrzebujemy solidnego i wydajnego modelu bazy danych do przechowywania przetłumaczonych treści w wielu językach”.

Załóżmy, że poproszono nas o zaprojektowanie modelu danych dla wielojęzycznej aplikacji e-commerce. Musielibyśmy przechowywać pola tekstowe, takie jak product_name oraz opis produktów w różnych językach. Musielibyśmy również przechowywać pola tekstowe w innych tabelach, takich jak customer tabeli, we wszystkich tych językach.

Aby zrozumieć, jak zaprojektować nasz model danych z myślą o tłumaczeniu treści, przeanalizujemy różne podejścia, korzystając z tych dwóch tabel. Każde z tych podejść ma zalety i wady. Przedstawione poniżej podejścia można rozszerzyć na inne tabele w modelu danych. Oczywiście dokładne podejście, które wybierzesz, będzie oparte na Twoich własnych wymaganiach.

Podejście 1 – dodawanie oddzielnych kolumn językowych dla każdego zamierzonego pola

To najprostsze podejście pod względem rozwoju. Można to zaimplementować poprzez dodanie jednej kolumny językowej dla każdego pola.




Zalety

  • Jest bardzo łatwy do wdrożenia.
  • Pisanie SQL w celu pobierania danych w dowolnym języku nie jest skomplikowane. Załóżmy, że chcę napisać zapytanie, aby pobrać dane produktu i klienta dla konkretnego zamówienia w języku francuskim. Kod wyglądałby tak:

    Select p.product_name_FR, p.description_FR, p.price, 
           c.name_FR, c.address_FR, c.contact_name 
    from order_line o, product p, customer c
    	Where o.product_id = p.id and o.customer_id = c.id
    	And id = ;
    

Wady

  • Nie ma skalowalności:za każdym razem, gdy dodawany jest nowy język, należy dodać dziesiątki dodatkowych kolumn w różnych tabelach.
  • Może to być czasochłonne, zwłaszcza jeśli wiele pól musi mieć wiele języków.
  • Deweloperzy w końcu piszą zapytanie pokazane poniżej, aby zarządzać wszystkimi istniejącymi językami. Tak więc wszystkie kody SQL w Twojej aplikacji muszą się zmienić po wprowadzeniu nowego języka. (Uwaga: @in_language oznacza aktualny język aplikacji; ten parametr pochodzi z interfejsu aplikacji, podczas gdy zaplecze pobiera rekordy).

    SELECT CASE @in_language 
                  WHEN ‘FR’ THEN p.product_name_FR
                  WHEN ‘DE’ THEN p.product_name_DE
                  DEFAULT THEN p.product_name_EN,
               p.price,
              CASE @in_language 
                  WHEN ‘FR’ THEN c.name_FR
                  WHEN ‘DE’ THEN c.name_DE
                  DEFAULT THEN c.name_EN,
              c.contact_name
    FROM order_line o, product p, customer c
    	WHERE o.product_id = p.id AND o.customer_id = c.id
    	AND id = ;
    

Podejście 2 – Tworzenie oddzielnej tabeli dla przetłumaczonego tekstu

W tym podejściu do przechowywania przetłumaczonego tekstu używana jest oddzielna tabela; w poniższym przykładzie nazwaliśmy tę tabelę translation . Zawiera jedną kolumnę dla każdego języka. Wartości, które zostały przetłumaczone z wartości pól na wszystkie odpowiednie języki, są przechowywane jako rekordy. Zamiast przechowywać rzeczywisty przetłumaczony tekst w tabelach poniżej, przechowujemy jego odniesienie do translation stół. Ta implementacja pozwala nam na stworzenie wspólnego repozytorium przetłumaczonego tekstu bez wprowadzania zbyt wielu zmian w istniejącym modelu danych.




Zalety

  • To dobre podejście, jeśli lokalizacja ma zostać zaimplementowana w istniejącym modelu danych.
  • Pojedyncza dodatkowa kolumna w translation tabela jest jedyną zmianą potrzebną po wprowadzeniu nowego języka.
  • Gdy oryginalny tekst jest taki sam we wszystkich tabelach, nie ma zbędnego przetłumaczonego tekstu. Na przykład:załóżmy, że nazwa klienta i nazwa produktu są identyczne. W takim przypadku tylko jeden rekord zostanie wstawiony do tabeli tłumaczeń, a ten sam rekord jest odnoszony zarówno do customer i product stoły.

Wady

  • Nadal wymaga zmiany modelu danych.
  • W tabeli mogą znajdować się niepotrzebne wartości NULL. Jeśli 1000 pól jest potrzebnych tylko dla jednego obsługiwanego języka, w efekcie tworzysz 1000 rekordów – i wiele wartości NULL.
  • Złożoność pisania SQL wzrasta wraz ze wzrostem liczby złączeń. A kiedy w translation tabeli, czasy wyszukiwania są wolniejsze.

    Napiszmy ponownie SQL dla instrukcji problemu z zarządzaniem językiem:

    SELECT CASE @in_language 
                  WHEN ‘FR’ THEN tp.text_FR
                  WHEN ‘DE’ THEN tp.text_DE
                  DEFAULT THEN p.product_name_EN,
               p.price,
              CASE @in_language 
                  WHEN ‘FR’ THEN tc.text_FR
                  WHEN ‘DE’ THEN tc.text_DE
                  DEFAULT THEN c.name_EN,
              c.contact_name
    FROM order_line o, product p, customer c, translation tp, translation tc
    	WHERE o.product_id = p.id AND o.customer_id = c.id
    	AND p.name_translation_id = tp.id
    	AND c.name_translation_id = tc.id
    	AND id = ;
    
    

Wariant podejścia opartego na tabeli tłumaczeń

Aby uzyskać lepszą wydajność podczas pobierania przetłumaczonego tekstu, możemy podzielić translation tabeli na wiele tabel. Rekordy możemy pogrupować według domeny, czyli jedna tabela dla customer , inny dla product itp.




Podejście 3 – Tabela tłumaczeń z wierszami dla każdego języka

Ta implementacja jest dość podobna do drugiego podejścia, ale przechowuje wartości przetłumaczonego tekstu w wierszach, a nie w kolumnach. Tutaj translation identyfikator tabeli pozostaje taki sam dla wartości pola w dowolnym przetłumaczonym języku. Złożony klucz podstawowy {id , language_id } jest przechowywany w tabeli tłumaczeń i przechowuje ten sam translation_id dla każdego pola z wieloma language_id .




Zalety

  • Ta implementacja pozwala programistom dość łatwo pisać SQL do wyszukiwania danych.
  • Łatwo jest również napisać OEM dla tego modelu.
  • Po dodaniu nowego języka nie są potrzebne żadne zmiany modelu danych; po prostu wstaw rekordy dla nowego języka.
  • Nie ma niepotrzebnego zużycia pamięci, gdy zestaw pól nie ma zastosowania do języka.
  • Zmniejszono złożoność zapytań SQL służących do pobierania danych. Spójrz na poniższy przykład:

    SELECT tp.text,
            p.price,
           tc.text,
            c.contact_name
    FROM order_line o, product p, customer c, translation tp, 
         translation tc, language l
    	WHERE o.product_id = p.id AND o.customer_id = c.id
    	AND p.name_translation_id = tp.id
    	AND c.name_translation_id = tc.id
                 AND tp.language_id = l.id
                 AND tc.language_id = l.id
                 AND l.name = @in_language
    	AND id = ;
    
    

Wady

  • W celu pobrania przetłumaczonych danych wymagana jest stosunkowo duża liczba połączeń.
  • Z czasem ogromna liczba rekordów może być potencjalnie przechowywana w translation stół. Ponieważ istnieje tylko jedna tabela tłumaczeń, cały przetłumaczony tekst zostanie do niej zrzucony. Gdy masz miliony pól do przetłumaczenia, a aplikacja obsługuje dużą liczbę języków, zapytanie o tłumaczenie w jednej tabeli byłoby czynnością czasochłonną. Możesz jednak podzielić tabelę tłumaczeń na podstawie języków lub obszarów tematycznych, jak wskazaliśmy na zakończenie drugiego podejścia.

Co jeśli połączymy podejścia 2 i 3?

W szczególności połączymy wariant podejścia 2 – dzieląc translation table – z myślą o wykorzystaniu wierszy w tabeli. Możemy łatwo przezwyciężyć minusy posiadania ogromnych rekordów w translation tabeli, tworząc wiele tabel w oparciu o domenę, tak jak zrobiliśmy to w wariancie Approach 2. Jeśli w tabeli tłumaczeń opartej na domenie znajduje się znaczna liczba rekordów, możemy dalej podzielić tabele na podstawie poszczególnych pól.




Podejście nr 4 – Tworzenie warstw encji dla pól tłumaczonych i pól nieprzetłumaczonych

W tym rozwiązaniu tabele encji zawierające jedno lub więcej przetłumaczonych pól są podzielone na dwie warstwy:jedną dla pól przetłumaczonych, a drugą dla pól nieprzetłumaczonych. W ten sposób tworzymy dla każdego osobne warstwy.




Zalety

  • Nie ma potrzeby dołączania do tabel tłumaczeń, jeśli dotyczy to tylko nieprzetłumaczonych pól. Dlatego nieprzetłumaczone pola uzyskują lepszą wydajność.
  • Relatywnie mniejsza liczba łączeń jest wymagana do pobrania przetłumaczonych tekstów.
  • Łatwo jest pisać OEM.
  • Kody SQL do pobierania przetłumaczonego tekstu są proste.
  • To sprawdzone podejście do włączania wielu języków w różne podmioty.

Aby to zademonstrować, oto przykładowe zapytanie, które pobierze przetłumaczony tekst:

SELECT pt.product_name, pt.description, p.price
FROM order_line o, product p, product_translation pt, language l
	WHERE o.product_id = p.id AND 
	AND p.id = pt.product_non_trans_id
	AND pt.language_id = l.id
               AND l.name = @in_language
	AND id = ;

Lokalizacja – wykraczanie poza tłumaczenie treści

Lokalizacja to nie tylko tłumaczenie treści aplikacji na inny język. Na uwagę zasługują również parametry kulturowe i funkcjonalne. Na przykład wartość daty jest sformatowana jako „MM/DD/RRRR” w Ameryce Północnej, ale w większości Azji jest zapisana jako „DD/MM/RRRR”.

Inny przykład dotyczy wyświetlania nazw w nagłówku aplikacji. W Stanach Zjednoczonych nazywanie kogoś po imieniu jest dopuszczalne, a nawet preferowane; w tej kulturze imię klienta jest wyświetlane w nagłówku, gdy tylko klient się zaloguje. Jednak w Japonii sytuacja jest odwrotna:nazywanie kogoś po imieniu jest niegrzeczne, a nawet raczej obraźliwe. Lokalizacja uwzględni to i pozwoli uniknąć używania imion dla japońskich odbiorców aplikacji.

Może być konieczne zapisanie parametrów lokalizacji na zapleczu aplikacji. Dzieje się tak bardzo w przypadku, gdy musisz zaprojektować logikę programu wokół lokalizacji. Prawdopodobnie możemy skategoryzować wszystkie takie parametry na kategorie kulturowe i funkcjonalne i wokół nich zbudować model danych.

Jeszcze jedna myśl o lokalizacji

Lokalizacja jest konieczna, gdy globalna marka wkracza na lokalne rynki. Aby zlokalizować aplikację, spójrz na duży obraz. Lokalizacja to coś więcej niż technicznie doskonała wydajność. Oznacza to również opanowanie lokalnych kultur, zachowań, a nawet sposobów myślenia i życia.

Co jeszcze można zrobić, aby aplikacja była dostosowywana lokalnie? Daj nam znać swoje przemyślenia w komentarzach.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak pracować z dziedziczeniem w Entity Framework Core

  2. Poziomy zgodności i podstawa szacowania kardynalności

  3. Aspekty ciągów w .NET

  4. Dynamiczne maskowanie danych oparte na proxy w FieldShield

  5. Repozytorium testowej bazy danych IRI-Windocks