Thiết kế cơ sở dữ liệu đa ngôn ngữ

1. Tiếp cận theo column

Nó có lẽ là một trong những cách đơn giản nhất. Khi cần thêm một ngôn ngữ mới thì những column nào cần dịch thì mình sẽ thêm nó vào table. Ví dụ dưới đây là có 3 ngôn ngữ cho hai column

 

Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    
    $table->string('title_vi');
    $table->string('title_en');
    $table->string('title_ja');

    $table->text('content_vi');
    $table->text('content_en');
    $table->text('content_ja');
    $table->timestamps();
});

 

Ưu điểm:

Đơn giản: dễ thực hiện

Dễ truy vấn: bạn không phải JOIN

Dữ liệu không bị lặp

Nhược điểm:

Khó cải thiện: nó chỉ làm việc tốt với 2 hoặc 3 ngôn ngữ, khi có nhiều ngôn ngữ thì nó không ổn

Khó để thêm một ngôn ngữ mới: Khi bạn cần thêm một ngôn ngữ mới, bạn cần phải thêm tất cả các column cần dịch vào bảng

Dư thừa các column: Khi các ngôn ngữ không phải bắt buộc, sẽ có trường hợp các cột mình không lưu gì mà để trống

Cần xác định trước ngôn ngữ cần dịch: Bạn cần phải xác định trước bạn cần dịch những ngôn ngữ nào để thêm column cho phù hợp.

 

2. Tiếp cận theo row

Cũng gần giống như hướng tiếp cận theo column, nhưng ở đây là dữ liệu lặp lại ở trong các row. Xem cí dụ bên dưới, khi đó mỗi khi có một ngôn ngữ mới thì trong bảng posts có hai  column title và content lại được lặp lại tương ứng với ngôn ngữ trong bảng languages có id của nó.

 

Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('language')->comment("ví dụ: en - tiếng anh, vi -tiếng việt, ja - tiếng nhật");
    $table->string('title');
    $table->text('content');
    $table->timestamps();
});

 

Ưu điểm:

Đơn giản: dễ thực hiện

Dễ truy vấn: Không cần JOIN

Nhược điểm:

Khó cải thiện:  giả sử có một cloumn không cần dịch cần thay đổi, thì bạn sẽ cần phải thay đổi tất cả các ngôn ngữ

Khó để thêm một ngôn ngữ mới: bạn cần phải lặp lại nhiều lần khi thêm một ngôn ngữ mới

Dư thừa dữ liệu: trong trường hợp các một số columns không bắt buộc thì các trường đấy bị trống

 

3. Tiếp cận theo một bảng dịch

Giải pháp này là một trong những cách rõ ràng nhất về cấu trúc cơ sở dữ liệu. Tất cả những nội dung cần dịch trong một bảng, Nó phù hợp với những web động mà có số lượng ngôn ngữ lớn hoặc có số lượng ngôn ngữ cố định và trong tương lại sẽ thêm ngôn ngữ mới. Hãy xem ví dụ dưới đây

// bảng ngôn ngữ
Schema::create('languages', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});
// bảng post
Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('title');
    $table->integer('content');
    $table->timestamps();
});
// bảng dich những column từ bảng post
Schema::create('post_translations', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('language_id');
    $table->integer('translation_id');
    $table->string('title');
    $table->text('content');
    $table->timestamps();
});

 

Ở đây column title và content trong bảng posts sẽ tương ứng với column translation_id trong bảng post_translations.

Ưu điểm:

Rõ ràng: có quan hệ với nhau

Dễ dàng thêm ngôn ngữ mới: không cần bạn phải thêm column vào bảng

Tất cả ngôn ngữ ở một bảng: dễ dàng cho việc đọc và sửa dữ liệu

Nhược điểm:

Truy vấn phức tạp: bạn cần phải join để lấy được ngôn ngữ

Khó sửa chữa: bạn cần phải truy vấn tất cả các bảng để thgao tác thêm sửa xóa

Tất cả ngôn ngữ nằm ở một bảng: nếu bảng bị lỗi thì dẫn đến tất cả dữ liệu đều bị lỗi

 

4. Tiếp cận theo hướng bổ sung thêm bảng dịch

Hãy xem ví dụ dưới đây

 

// bảng ngôn ngữ
Schema::create('languages', function (Blueprint $table) {
    $table->increments('id');
    $table->string('name');
    $table->timestamps();
});
// bảng post
Schema::create('posts', function (Blueprint $table) {
    $table->increments('id');
    $table->timestamps();
});
// bảng dich những column từ bảng post
Schema::create('post_translations', function (Blueprint $table) {
    $table->increments('id');
    $table->integer('language_id');
    $table->integer('post_id');
    $table->string('title');
    $table->text('content');
    $table->timestamps();
});

 

Ở trong bảng posts, những columns nào không cần dịch thì mình vẫn dữ nguyên ở bảng đấy, còn những column nào cần dịch thì mình sẽ chuyển nó sang bảng post_translations , như ở ví dụ này column title và content là cần dịch nên sẽ chuyển sang bảng post_translations.

Ưu điểm:

Rõ ràng: có quan hệ với nhau

Dễ dàng thêm ngôn ngữ mới: không cần bạn phải thêm column vào bảng

Các column dữ nguyên tên: không cần phải thêm hầu tố "_lang" vào sau column

Truy vấn dễ: đơn giản, bạn chỉ cần join là xong.

Nhược điểm:

Số lượng bảng tăng lên: Nếu bạn tạo các bảng đa ngôn ngữ cho tất cả các bảng thì số lượng bảng sẽ tăng lên

Kết luận: Trên đây là 4 cách tiếp cận để thiết kế cơ sở dữ liệu đa ngôn ngữ phổ biến, bạn hoàn toàn có thể chỉnh sửa chúng sao cho phù hợp với hệ thống của mình. Và hãy nhớ rằng, bạn chọn cách nào cho dự án của mình tùy thuộc vào dự án của bạn thế nào. Các bạn có thể tham khảo trên google rất nhiều.