programing

다국어 데이터를 유지하는 데 가장 적합한 데이터베이스 구조는 무엇입니까?

shortcode 2022. 9. 13. 22:35
반응형

다국어 데이터를 유지하는 데 가장 적합한 데이터베이스 구조는 무엇입니까?

중복 가능성:
다국어 데이터베이스용 스키마

다음은 예를 제시하겠습니다.

[ 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

반응형