다국어 데이터를 보관하기 위한 최적의 데이터베이스 구조는?
중복 가능성:
다국어 데이터베이스용 스키마
다음은 예입니다.
[ products ]
id (INT)
name-en_us (VARCHAR)
name-es_es (VARCHAR)
name-pt_br (VARCHAR)
description-en_us (VARCHAR)
description-es_es (VARCHAR)
description-pt_br (VARCHAR)
price (DECIMAL)
문제: 모든 새로운 언어는 테이블 구조를 수정해야 합니다.
다음은 또 다른 예입니다.
[ products-en_us ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
[ products-es_es ]
id (INT)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
문제: 모든 새 언어는 새 테이블을 생성해야 하며 "가격" 필드는 모든 테이블에 복제됩니다.
다음은 또 다른 예입니다.
[ languages ]
id (INT)
name (VARCHAR)
[ products ]
id (INT)
price (DECIMAL)
[ translation ]
id (INT, PK)
model (VARCHAR) // product
field (VARCHAR) // name
language_id (INT, FK)
text (VARCHAR)
문제: 어렵다?
세 번째 예는 실제로 문제가 일반적으로 해결되는 방식입니다. 어렵지만 가능합니다.
번역 테이블에서 제품에 대한 참조를 제거하고 필요한 곳에 번역에 대한 참조를 두십시오(반대).
[ products ]
id (INT)
price (DECIMAL)
title_translation_id (INT, FK)
[ translation ]
id (INT, PK)
neutral_text (VARCHAR)
-- other properties that may be useful (date, creator etc.)
[ translation_text ]
translation_id (INT, FK)
language_id (INT, FK)
text (VARCHAR)
대안으로(특히 좋은 것은 아님) 단일 필드를 갖고 모든 번역을 함께 병합된 상태로 유지할 수 있습니다(예: XML).
<translation>
<en>Supplier</en>
<de>Lieferant</de>
<fr>Fournisseur</fr>
</translation>
방법 3과 유사:
[languages]
id (int PK)
code (varchar)
[products]
id (int PK)
neutral_fields (mixed)
[products_t]
id (int FK)
language (int FK)
translated_fields (mixed)
PRIMARY KEY: id,language
따라서 각 테이블에 대해 번역된 필드를 보유하는 다른 테이블(내 경우에는 "_t" 접미사 포함)을 만드십시오. 당신이 SELECT * FROM products
, 단순히 ... LEFT JOIN products_t ON products_t.id = products.id AND products_t.language = CURRENT_LANGUAGE
.
그렇게 어렵지 않고 두통을 피할 수 있습니다.
JOIN의 수를 줄이기 위해 2개의 별도 테이블에 번역된 것과 번역되지 않은 것을 별도로 유지할 수 있습니다.
[ products ]
id (INT)
price (DECIMAL)
[ products_i18n ]
id (INT)
name (VARCHAR)
description (VARCHAR)
lang_code (CHAR(5))
내 $DAYJOB에서 우리는 I18N에 대해 gettext를 사용합니다. 데이터베이스 테이블에서 모든 영어 텍스트를 추출하여 마스터 messages.pot에 추가 하는 플러그인을 xgettext.pl에 작성했습니다 .
그것은 매우 잘 작동합니다 - 번역가는 번역을 할 때 오직 하나의 파일인 po 파일만 처리합니다. 번역을 할 때 데이터베이스 항목을 만지작거릴 필요가 없습니다.
[언어] id(int PK) 코드(varchar)
[products]
id (int PK)
name
price
all other fields of product
id_language ( int FK )
실제로 이 방법을 사용하지만 제 경우에는 제품의 관점에서 볼 때 CMS의 다양한 페이지에 대해 이 작업이 꽤 좋습니다.
제품이 많은 경우 5개 또는 6개 언어로 하나의 제품을 업데이트하는 것이 골칫거리일 수 있지만 레이아웃 작업의 문제입니다.
네 번째 솔루션은 어떻습니까?
[ products ]
id (INT)
language (VARCHAR 2)
name (VARCHAR)
description (VARCHAR)
price (DECIMAL)
*translation_of (INT FK)*
*Translation_of*는 자체의 FK 입니다. 기본 언어를 추가할 때 *translation_of*는 Null로 설정됩니다. 그러나 두 번째 언어를 추가할 때 *translation_of*는 기본 제품 언어 ID를 사용합니다.
SELECT * FROM products WHERE id = 1 AND translation_of = 1
이 경우 id가 1인 제품에 대한 모든 번역을 얻습니다.
SELECT * FROM products WHERE id = 1 AND translation_of = 1 AND language = 'pl'
우리는 폴란드어 번역으로만 제품을 얻습니다. 두 번째 테이블과 JOINS가 없습니다.
다대다 관계를 갖습니다.
데이터 테이블, 언어 테이블 및 data_language 테이블이 있습니다.
data_language 테이블에는
아이디, 데이터 아이디, 언어 아이디
나는 그것이 당신을 위해 가장 잘 작동 할 수 있다고 생각합니다.
우리는 이 개념을 웹사이트(하루에 600k 조회수)에 사용하고 (놀랍게도) 작동합니다. 물론 캐싱 및 쿼리 최적화와 함께.
[attribute_names]
id (INT)
name (VARCHAR)
[languages_names]
id (INT)
name (VARCHAR)
[products]
id (INT)
attr_id (INT)
value (MEDIUMTEXT)
lang_id (INT)
ReferenceURL : https://stackoverflow.com/questions/2227985/whats-the-best-database-structure-to-keep-multilingual-data
'IT이야기' 카테고리의 다른 글
MFMailComposeViewController의 MailComposer 시트에 UIImage를 추가하는 방법 (0) | 2021.10.10 |
---|---|
UITextField: 키보드가 나타날 때 보기 이동 (0) | 2021.10.09 |
C#에서 익명 개체의 속성 반복 (0) | 2021.10.09 |
문자와 혼합된 숫자만 인식하도록 tesseract를 만드는 방법 (0) | 2021.10.09 |
Android에서 카메라 손전등 사용 (0) | 2021.10.09 |