Apa praktik terbaik untuk desain basis data multi-bahasa? [Tutup]

193

Apa cara terbaik untuk membuat basis data multi-bahasa? Untuk membuat tabel terlokalisasi untuk setiap tabel membuat desain dan kueri kompleks, dalam kasus lain menambahkan kolom untuk setiap bahasa adalah sederhana tetapi tidak dinamis, tolong bantu saya untuk memahami apa yang terbaik untuk memilih aplikasi perusahaan

Arsen Mkrtchyan
sumber

Jawaban:

223

Apa yang kami lakukan adalah membuat dua tabel untuk setiap objek multibahasa.

Misalnya, tabel pertama hanya berisi data netral-bahasa (kunci utama, dll.) Dan tabel kedua berisi satu catatan per bahasa, yang berisi data yang dilokalkan plus kode ISO bahasa tersebut.

Dalam beberapa kasus kami menambahkan bidang DefaultLanguage, sehingga kami dapat kembali ke bahasa itu jika tidak ada data yang dilokalkan tersedia untuk bahasa yang ditentukan.

Contoh:

Table "Product":
----------------
ID                 : int
<any other language-neutral fields>


Table "ProductTranslations"
---------------------------
ID                 : int      (foreign key referencing the Product)
Language           : varchar  (e.g. "en-US", "de-CH")
IsDefault          : bit
ProductDescription : nvarchar
<any other localized data>

Dengan pendekatan ini, Anda dapat menangani bahasa sebanyak yang diperlukan (tanpa harus menambahkan bidang tambahan untuk setiap bahasa baru).


Pembaruan (2014-12-14): silakan lihat jawaban ini , untuk beberapa informasi tambahan tentang implementasi yang digunakan untuk memuat data multibahasa ke dalam suatu aplikasi.

M4N
sumber
15
bagaimana jika satu-satunya bidang bahasa netral adalah id? dan bagaimana tepatnya Anda memasukkan referensi kunci asing saat memasukkan baris?
Timo Huovinen
4
Sangat lucu, bahwa saya merancang skema database untuk CMS multibahasa dan memiliki pertanyaan ini juga di kepala saya. Saya memilih pendekatan ini, bahkan sebelum saya melihat jawaban ini! Terima kasih atas jawaban ini!
Patrick Manser
5
Satu hal yang perlu diperhatikan di sini adalah bahwa tidak akan ada PK pada tabel ini atau ID dan Bahasa perlu menjadi PK komposit. Entah itu, atau Anda perlu menambahkan bidang ProductTranslationId, mungkin sebagai identitas.
Daniel Lorenz
1
@ Luca: Saya menjawab pertanyaan Anda, menunjukkan implementasi apa yang saya gunakan untuk memuat data.
M4N
1
@ AarónGutiérrez Nah, cukup lucu Anda membuat tabel dengan satu kolom bernama id: D. Untuk menjelaskan, masing-masing idmewakili makna di mana Anda dapat melampirkan kata-kata dari bahasa apa pun di tabel relasional, sehingga Anda mendapatkan dua tabel, meaning(id) dan word(id, meaning_id), iddi wordtabel mewakili kata id, iddi meaningmewakili makna yang universal.
Timo Huovinen
18

Saya merekomendasikan jawaban yang diposting oleh Martin.

Tetapi Anda tampaknya khawatir bahwa pertanyaan Anda menjadi terlalu rumit:

Untuk membuat tabel terlokalisasi untuk setiap tabel membuat desain dan kueri ...

Jadi Anda mungkin berpikir, bahwa alih-alih menulis pertanyaan sederhana seperti ini:

SELECT price, name, description FROM Products WHERE price < 100

... Anda harus mulai menulis pertanyaan seperti itu:

SELECT
  p.price, pt.name, pt.description
FROM
  Products p JOIN ProductTranslations pt
  ON (p.id = pt.id AND pt.lang = "en")
WHERE
  price < 100

Bukan perspektif yang sangat cantik.

Tetapi alih-alih melakukannya secara manual, Anda harus mengembangkan kelas akses basis data Anda sendiri, yang melakukan pra-parsing SQL yang berisi markup lokalisasi khusus Anda dan mengubahnya menjadi SQL aktual yang perlu Anda kirim ke database.

Menggunakan sistem itu mungkin terlihat seperti ini:

db.setLocale("en");
db.query("SELECT p.price, _(p.name), _(p.description)
          FROM _(Products p) WHERE price < 100");

Dan saya yakin Anda bisa melakukan itu lebih baik lagi.

Kuncinya adalah membuat tabel dan bidang Anda dinamai secara seragam.

Rene Saarsoo
sumber
pertanyaan lainnya adalah, untuk membuat satu objek bisnis untuk produk? atau untuk membuat dua ... dalam kasus pertama mudah untuk bekerja dengan item itu, dalam 2 mudah untuk menulis CMS
Arsen Mkrtchyan
14

Saya menemukan jenis pendekatan ini bekerja untuk saya:

Produk ProdukDetail Negara
========= ================== =========
ProductId ProductDetailId CountryId
- etc - ProductId CountryName
            Bahasa CountryId
            Nama Produk - dll -
            Deskripsi Produk
            - dll -

Tabel ProductDetail menampung semua terjemahan (untuk nama produk, deskripsi dll.) Dalam bahasa yang ingin Anda dukung. Bergantung pada persyaratan aplikasi Anda, Anda mungkin ingin memecah tabel Negara untuk menggunakan bahasa daerah juga.

Nick
sumber
Saya memilih pendekatan yang sama untuk proyek yang sedang saya kerjakan karena lokasi saya yang berbeda mengandung informasi yang sangat spesifik tentang sistem unit dan langkah-langkah yang akan ditampilkan kepada pengguna.
califrench
8
Negara dan bahasa (lokal) adalah hal yang berbeda. Dan kode bahasa ISO adalah kunci alami, Anda menghilangkan gabungan yang tidak perlu dari bahasa ke negara.
gavenkoa
10

Saya menggunakan pendekatan berikutnya:

Produk

ProductID OrderID, ...

Info produk

ProductID Judul Nama LanguageID

Bahasa

LanguageID Nama Budaya, ....

omoto
sumber
2

Solusi Martin sangat mirip dengan solusi saya, namun bagaimana Anda menangani deskripsi default ketika terjemahan yang diinginkan tidak ditemukan?

Apakah itu memerlukan IFNULL () dan pernyataan SELECT lain untuk setiap bidang?

Terjemahan default akan disimpan dalam tabel yang sama, di mana bendera seperti "isDefault" menunjukkan apakah deskripsi tersebut adalah deskripsi default jika tidak ada yang ditemukan untuk bahasa saat ini.

doM
sumber
1
@GorrillaApe: lihat jawaban ini untuk contoh bagaimana kembali ke bahasa default, jika bahasa yang diinginkan tidak ditemukan: stackoverflow.com/a/27474681/19635
M4N