Giả sử rằng mảng bản dịch không được phép có nhiều hơn một mục có cùng mã ngôn ngữ
{
"_id" : ObjectId["abcdefg"],
"category" : "CategoryName",
"key" : "YourStringKey",
"text" : "The text to translate",
"translations" : [
{
"_id" : ObjectId["zyxwvu"],
"language" : "es",
"text" : "Spanish translation"
}
]
}
Trong SQL, bạn có các bản dịch của mình dưới dạng một bảng riêng biệt, có thể giống như thế này Bạn có thể sử dụng một giao dịch để CHỌN, kiểm tra xem bạn có cần chèn hoặc cập nhật hay không, sau đó thực hiện thao tác ghi Hoặc, nếu bạn không muốn sử dụng giao dịch, bạn có thể tránh chèn trùng lặp bằng cách sử dụng CHÈN. CHỌN với THAM GIA TRÁIBạn sẽ làm điều đó như thế nào trong SQL?
CREATE TABLE MasterText [
MasterText INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
Category VARCHAR[30] NOT NULL,
Key VARCHAR[30] NOT NULL,
SourceText TEXT
]
CREATE TABLE Translations [
TranslationID INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY,
MasterTextID INTEGER UNSIGNED NOT NULL,
TranslationLang VARCHAR[8] NOT NULL,
TranslatedText TEXT,
FOREIGN KEY [MasterTextID] REFERENCES MasterText[MasterTextID]
]
SQL - Giao dịch
START TRANSACTION
SELECT TranslationID FROM Translations .. [see if the row exists]
// if the row already exists:
UPDATE Translations ...
// if it did not exist:
INSERT INTO Translations
COMMIT
END TRANSACTION
SQL - Chèn/Chọn
INSERT INTO Translations
[MasterTextID, TranslationLang, TranslatedText]
SELECT mt.MasterTextID, 'fr', 'French translation'
FROM MasterText mt
LEFT JOIN Translations t
ON mt.MasterTextID = t.MasterTextID
AND t.TranslationLang = 'fr'
WHERE mt.Category = 'CategoryName'
AND mt.Key = 'YourStringKey'
AND t.TranslationID IS NULL
Điều này đảm bảo bạn sẽ không chèn nhiều hơn một - ngay cả trong điều kiện chạy đua. Sau đó, bạn có thể theo dõi một bản cập nhật để hoàn thành "upsert"
SQL - Khi cập nhật khóa trùng lặp
Hoặc, nếu bạn đang sử dụng MySQL, bạn có thể sử dụng "CẬP NHẬT KHÓA TRÊN DUPLICATE"
INSERT INTO Translations
[MasterTextID, TranslationLang, TranslatedText]
VALUES [$masterTextID, 'fr', 'French translation']
ON DUPLICATE KEY
UPDATE TranslatedText = 'French translation'
Sai. Tìm/Chèn hoặc Cập nhật
Mongo không cung cấp giao dịch, vì vậy bạn không thể thực hiện tìm kiếm và sau đó thực hiện
if [exists] {
update[];
} else {
insert[];
}
Sai. Cập nhật với Upsert
Mongo có tính năng sau
db.translatablestrings.update[
{ category: 'CategoryName', key: 'YourStringKey' },
{ .. your update command },
{ upsert: true }
]
Vấn đề là chức năng "upsert" trong MongoDB chỉ được tạo để nâng cấp toàn bộ tài liệu - không phải cho các tài liệu con
Sai. đẩy $
Bạn không thể đơn giản thực hiện $push. Nếu hai quy trình xung đột thực hiện $push [hơi-] đồng thời, bạn sẽ nhận được hai bản dịch cho cùng một ngôn ngữ - điều này vi phạm các quy tắc của ứng dụng của bạn
$ mongo safeupserts
db.translatablestrings.update[
{ category: 'CategoryName', key: 'YourStringKey' },
{ $push: { translations:
{ _id: new ObjectId[], language: 'fr', text: 'French translation' }
} }
]
WriteResult[{ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 }]
Đây là vấn đề tương tự mà bạn gặp phải nếu bạn thực hiện hai lần chèn trong SQL, nhưng không có CHỌN và THAM GIA TRÁI để kiểm tra các bản sao
Sai. đẩy $
Điều kiện cạnh tranh của việc sử dụng $push có thể dẫn đến trùng lặp
________số 8_______Sai. Trường phiên bản
Một số phương pháp đề xuất sử dụng phương pháp chọn, sau đó chèn hoặc cập nhật và dựa vào trường phiên bản để đảm bảo rằng bạn không ghi đè lên nội dung nào đó. Ví dụ
Chức năng của tôi là, được cung cấp một groupid, personId và Liked , tìm xem có tài liệu nào tồn tại với GroupId đã cho hay không. Nếu tồn tại, tôi nên cập nhật tài liệu đó với personId và Liked nếu bản ghi không xuất hiện, nếu id người đó cũng xuất hiện, tôi không nên thêm cùng một người vào mảng