Cơ sở dữ liệu đằng sau Giao diện người dùng đa ngôn ngữ


8

Câu hỏi này là về một vấn đề hơi phức tạp hơn vấn đề đã được giải quyết trong những câu hỏi cũ này, tất cả đều là bản sao của nhau:

Đề xuất cấu trúc cơ sở dữ liệu cho đa ngôn ngữ (tháng 6 năm 2011)

Cấu trúc cơ sở dữ liệu tốt nhất để giữ dữ liệu đa ngôn ngữ là gì? (Tháng 2 năm 2010)

Thực hành tốt nhất cho thiết kế cơ sở dữ liệu đa ngôn ngữ là gì? (Tháng 5 năm 2009)

Lược đồ cho cơ sở dữ liệu đa ngôn ngữ (tháng 11 năm 2008)


Lược đồ cơ sở dữ liệu phổ biến nhất để sao lưu giao diện người dùng đa ngôn ngữ dường như có tất cả các văn bản được dịch của tất cả các ngôn ngữ trong một bảng với 3 cột: id văn bản, mã ngôn ngữ và chính văn bản. Id văn bản và mã ngôn ngữ cùng nhau tạo nên khóa chính.

Điều đó rất tốt, nhưng bây giờ hãy xem xét một sự phức tạp: giả sử rằng các văn bản cần phải được tìm kiếm. Giả sử, ví dụ, đây là một cửa hàng điện tử đa ngôn ngữ. Điều này có nghĩa là đối với mỗi danh mục sản phẩm được nhập vào cơ sở dữ liệu, chủ cửa hàng sẽ nhập tên của danh mục sản phẩm theo từng ngôn ngữ được hỗ trợ và sau đó người mua hàng sẽ có thể tìm kiếm danh mục sản phẩm theo tên, bằng ngôn ngữ riêng của họ .

Có một vấn đề: Đối chiếu .

Các ngôn ngữ khác nhau có trình tự đối chiếu khác nhau và trình tự đối chiếu hoạt động cho một ngôn ngữ không hoạt động cho ngôn ngữ khác. Vì vậy, nếu tất cả các văn bản của tất cả các ngôn ngữ nằm trên một cột duy nhất, chúng sẽ có chuỗi đối chiếu nào? Làm thế nào chúng ta sẽ truy vấn cơ sở dữ liệu để tìm id văn bản của một văn bản cụ thể? Mặc dù trong tính chính xác và hiệu suất tìm kiếm sản phẩm web có thể không quá quan trọng, vì mục đích của cuộc thảo luận này, chúng ta hãy cho rằng chúng thực sự quan trọng.

Hầu hết các quản trị viên cơ sở dữ liệu đều quen thuộc với khái niệm đối chiếu theo nghĩa "đối chiếu cơ sở dữ liệu". May mắn thay, đó chỉ là đối chiếu mặc định, được sử dụng nếu không có thông tin đối chiếu nào khác, nhưng cũng tồn tại những nơi khác, nơi đối chiếu có thể được chỉ định:

  • Lệnh SQL CREATE INDEX hỗ trợ đặc tả đối chiếu. (Mặc dù có tin đồn rằng Microsoft SQL Server không hỗ trợ; có ai biết về điều đó không?)

  • Câu lệnh SQL SELECT cũng hỗ trợ đối chiếu, nhưng trong trường hợp này, đặc tả đối chiếu hoạt động như một hàm, gây ra quét chỉ mục thay vì tra cứu chỉ mục, một cái gì đó có thể không thể chấp nhận được nếu chúng ta muốn hiệu suất. (Sau đó, một lần nữa, nếu đó là điều tốt nhất chúng ta có thể có, nó có thể tốt hơn không có gì.)

  • Tôi cũng nghe nói rằng trên Microsoft SQL Server, bạn có thể có các cột được tính toán không tồn tại, trên đó bạn có thể chỉ định đối chiếu và tạo một chỉ mục được lọc, mặc dù tôi chưa bao giờ nghe về điều này trước đây và nếu đó chỉ là Microsoft-SQL-Server tính năng, sau đó tôi không muốn sử dụng nó, bất kể nó tuyệt vời và được nghĩ ra như thế nào.

Vì vậy, xét về tất cả những điều đó, làm thế nào để chúng tôi cấu trúc cơ sở dữ liệu của chúng tôi và làm thế nào để chúng tôi thực hiện các truy vấn của mình, nếu mục tiêu là một cơ sở dữ liệu đa ngôn ngữ có thể cập nhật và có thể tìm kiếm?


Câu hỏi này được lấy cảm hứng từ một cuộc thảo luận diễn ra ở đây: làm thế nào nvarchar (tối đa) lưu trữ dữ liệu trong cơ sở dữ liệu sẽ nhanh nếu một số dữ liệu ít hơn 4000 ký tự?


2
Nếu một tính năng chỉ dành cho sản phẩm của Microsoft thực sự tuyệt vời và được cân nhắc kỹ lưỡng, thì nó sẽ có cơ hội công bằng để nhận được sự hỗ trợ trong các sản phẩm tương tự của các nhà cung cấp khác kịp thời. Chỉ là một ý nghĩ.

Câu trả lời:


8

thể lưu trữ các chuỗi với các đối chiếu khác nhau trong cùng một cột bằng SQL_VariANT :

CREATE TABLE dbo.Localized
(
    text_id     INTEGER NOT NULL,
    lang_id     INTEGER NOT NULL,
    text_body   SQL_VARIANT NOT NULL,

    CONSTRAINT [PK dbo.Localized text_id, lang_id]
        PRIMARY KEY CLUSTERED (text_id, lang_id),
)
GO
INSERT dbo.Localized
    (text_id, lang_id, text_body)
VALUES
    (1001, 2057, N'Database problems' COLLATE Latin1_General_CI_AS);
GO
INSERT dbo.Localized
    (text_id, lang_id, text_body)
VALUES
    (1001, 1025, N'قاعدة بيانات المشاكل' COLLATE Arabic_CI_AS)

Thiết kế này có một số nhược điểm (bao gồm bị giới hạn ở 8000 byte), nhất là trong khu vực tìm kiếm: SQL_VARIANTkhông thể được lập chỉ mục toàn văn bản và một số tính năng so sánh chuỗi (ví dụ LIKE) không thể được sử dụng trực tiếp. Mặt khác, nó có thể tạo ra một chỉ số thường xuyên trên SQL_VARIANTvà thực hiện các so sánh cơ bản hơn (ví dụ như <, =,>) theo kiểu đối chiếu nhận thức:

CREATE UNIQUE INDEX uq1 ON dbo.Localized (text_body)
GO
-- One row
SELECT
    l.*
FROM dbo.Localized AS l 
WHERE
    l.text_body = CONVERT(SQL_VARIANT, N'Database problems' COLLATE Latin1_General_CI_AS)

-- No rows (and no collation error!)
SELECT
    l.*
FROM dbo.Localized AS l
WHERE
    l.text_body = CONVERT(SQL_VARIANT, N'Database problems' COLLATE Arabic_CI_AS)

-- One row, index seek, manual version of "LIKE 'D%'"
SELECT
    l.*
FROM dbo.Localized AS l 
WHERE
    l.text_body >= CONVERT(SQL_VARIANT, N'D' COLLATE Latin1_General_CI_AS)
    AND l.text_body < CONVERT(SQL_VARIANT, N'E' COLLATE Latin1_General_CI_AS)

Chúng tôi cũng có thể viết các loại thủ tục thông thường:

CREATE PROCEDURE dbo.GetLocalizedString
    @text_id    INTEGER,
    @lang_id    INTEGER,
    @text_body  SQL_VARIANT OUTPUT
AS
BEGIN
    SELECT
        @text_body = l.text_body
    FROM dbo.Localized AS l
    WHERE
        l.text_id = @text_id
        AND l.lang_id = @lang_id
END
GO
DECLARE @text SQL_VARIANT

EXECUTE dbo.GetLocalizedString
    @text_id = 1001,
    @lang_id = 1025,
    @text_body = @text OUTPUT

SELECT @text

Tất nhiên, lập chỉ mục toàn văn bản cũng có vấn đề trong thiết kế "bảng duy nhất cho tất cả các bản dịch", vì lập chỉ mục toàn văn bản (tất cả nhưng) yêu cầu cài đặt id ngôn ngữ cho mỗi cột . Thiết kế nhiều bảng được mô tả bởi Joop Eggen có thể được lập chỉ mục toàn văn bản (mặc dù nó sẽ tự nhiên yêu cầu một chỉ mục trên mỗi bảng).

Tùy chọn chính khác là có một cột trên mỗi miền trong bảng cơ sở:

CREATE TABLE dbo.Example
(
    text_id     INTEGER NOT NULL,
    text_2057   NVARCHAR(MAX) COLLATE Latin1_General_CI_AS NULL,
    text_1025   NVARCHAR(MAX) COLLATE Arabic_CI_AS NULL,

    CONSTRAINT [PK dbo.Example text_id]
        PRIMARY KEY CLUSTERED (text_id)
)

Sự sắp xếp này có một sự đơn giản nhất định và hoạt động tốt với lập chỉ mục toàn văn bản, mặc dù nó yêu cầu một cột mới được thêm vào với mỗi ngôn ngữ mới, và nhiều nhà phát triển thấy loại cấu trúc này không phù hợp và không đạt yêu cầu để làm việc.

Mỗi lựa chọn thay thế đều có những ưu điểm và nhược điểm, và sẽ yêu cầu sự gián tiếp ở mức độ này hay mức độ khác, vì vậy nó có thể phụ thuộc vào nơi mà các nhà phát triển quan tâm cảm thấy hạnh phúc nhất khi xác định vị trí đó. Tôi tưởng tượng hầu hết mọi người sẽ thích thiết kế nhiều bàn cho hầu hết các mục đích.


Tôi có thể sử dụng một bảng riêng biệt thay vì một cột riêng biệt để bố trí vật lý tốt hơn: đó là câu trả lời của tôi nói rằng đã truyền cảm hứng cho câu hỏi này dba.stackexchange.com/a/9954/630
gbn

5

Rõ ràng bạn muốn có một bảng cho mỗi ngôn ngữ: xxx_en , xxx_fr , xxx_eo . Điều đó sẽ tối ưu hơn và cho phép các bộ sưu tập phụ thuộc ngôn ngữ. Thậm chí có thể tưởng tượng rằng bạn có cơ sở dữ liệu cho mỗi ngôn ngữ [en] [xxx] , [fr] [xxx] , [eo] [xxx] .

Các chi tiết kỹ thuật sau đó có tầm quan trọng cao (có thể hoặc không thể tối ưu hóa nhiều hơn).

Các phím văn bản thực tế đi trên một bảng xxx .


2
Vấn đề với điều này là nó rất không liên quan.
Mike Nakis

Vâng, kinh nghiệm của tôi là, tìm kiếm văn bản đó, cho dù db được hỗ trợ hay tự thực hiện, rất khó để tích hợp một cách tương đối. Cảm ơn vì đã cho một điểm nào.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.