다국어 데이터를 유지하는 데 가장 적합한 데이터베이스 구조는 무엇입니까?
중복 가능성:
다국어 데이터베이스용 스키마
다음은 예를 제시하겠습니다.
[ 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)
문제: 어려운가?
방법 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
.
그렇게 힘들지도 않고, 두통도 없고요.
세 번째 예는 실제로 문제를 해결하는 방법입니다.어렵지만 할 수 있어
번역 테이블에서 제품에 대한 참조를 삭제하고 필요에 따라 번역에 대한 참조를 추가합니다(반대).
[ 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)
다른 방법(특히 좋은 필드는 아님)으로, 1개의 필드를 가지고, 거기에 있는 모든 변환을 Marge 해 둘 수 있습니다(XML 등).
<translation>
<en>Supplier</en>
<de>Lieferant</de>
<fr>Fournisseur</fr>
</translation>
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 파일 1개뿐입니다.번역할 때 데이터베이스 엔트리를 만지작거리지 않습니다.
[languages] 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 로 설정되어 있습니다.단, 제2언어를 추가할 경우 *translation_of*는 primary productkt 언어 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 테이블에는
id, data_id, language_id
그게 너한테 가장 좋을 것 같아.
이 개념을 웹 사이트(하루 60만 뷰)에 사용하고 있으며, (놀랍게도) 작동합니다.캐싱 및 쿼리 최적화와 함께 확실합니다.
[attribute_names]
id (INT)
name (VARCHAR)
[languages_names]
id (INT)
name (VARCHAR)
[products]
id (INT)
attr_id (INT)
value (MEDIUMTEXT)
lang_id (INT)
언급URL : https://stackoverflow.com/questions/2227985/whats-the-best-database-structure-to-keep-multilingual-data
'programing' 카테고리의 다른 글
Java에서 루프를 위한 확장의 마지막 반복 (0) | 2022.09.18 |
---|---|
Java에서 Base64 데이터 디코딩 (0) | 2022.09.13 |
MySQL(퍼포먼스 및 스토리지)의 특수한 절차 (0) | 2022.09.13 |
숫자에서 중요하지 않은 후행 0을 제거하시겠습니까? (0) | 2022.09.13 |
Java 프로그램 종료 (0) | 2022.09.13 |