Chèn hoặc cập nhật trình tạo truy vấn Laravel
Phát hành vào ngày 13 tháng 10 năm 2020, Laravel 8. 10 đi kèm với việc bổ sung phương thức 6 mới trên trình tạo truy vấn cơ sở dữ liệu (và do đó, các truy vấn dựa trên Eloquent cũng vậy). Điều này cho phép bạn thực hiện các truy vấn "chèn hoặc cập nhật" hiệu quả hơn nhiều - điều này sẽ hữu ích khi nhập các lô dữ liệu lớn Show
TLDR. Tại sao sử dụng nó?, Nó hoạt động như thế nào?, Nó hoạt động như thế nào? Một ví dụ thực tế về việc sử dụng upsert()Cho đến thời điểm hiện tại, trình tạo truy vấn cơ sở dữ liệu của Laravel đã hỗ trợ việc chèn hoặc cập nhật nhiều hàng (lô dữ liệu) cùng một lúc thông qua các phương thức 7 và 8. Ngoài ra còn có một phương pháp 9 ít được biết đến hơn sẽ chèn một loạt dữ liệu, bỏ qua mọi lỗi (chẳng hạn như một khóa duy nhất đã tồn tại)Chúng tôi cũng có phương pháp 0 trên các mô hình Eloquent cung cấp một tập hợp các thuộc tính, cập nhật một mô hình hiện có hoặc nếu nó không tồn tại, nó sẽ tạo ra nó. Tuy nhiên, điều này chỉ có thể được sử dụng trên một hàng/mô hình tại một thời điểm - nếu chúng tôi có 125.000 hàng để chèn hoặc cập nhật, chúng tôi sẽ phải gọi phương thức Eloquent đó 125.00 lần. Đằng sau hậu trường, điều này thực sự thực hiện hai truy vấn trong cơ sở dữ liệu - một để kiểm tra mục hiện có và một để thực hiện 1 hoặc 0 - vì vậy điều đó có nghĩa là chạy 250.000 truy vấn. Điều đó có thể chậmVì vậy, hãy tưởng tượng chúng ta có một tệp CSV chứa dữ liệu cho 125.000 sản phẩm mà chúng ta cần nhập vào cơ sở dữ liệu của mình một cách hiệu quả nhất có thể. Không vấn đề gì, chúng ta có thể sử dụng phương thức 7 trên trình tạo truy vấn để chèn nhiều hàng cùng một lúcChuyển nhanh đến 4 tuần sau, chúng tôi có tệp CSV mới về dữ liệu sản phẩm - chi tiết của 125.000 sản phẩm đã được cập nhật và 25.000 sản phẩm mới đã được thêm vào. Trong cơ sở dữ liệu của chúng tôi, chúng tôi cần cập nhật các sản phẩm hiện có và chèn những sản phẩm mới. Để làm điều này, chúng tôi cần biết sản phẩm nào chúng tôi đã có và sản phẩm nào mới để chúng tôi có thể thực hiện truy vấn 1 hoặc 0Thay vì sử dụng 0 150.000 lần cho mỗi hàng trong tệp CSV, hãy bắt đầu bằng cách chia nhỏ tệp CSV thành các lô nhỏ hơn, chẳng hạn như 5.000 sản phẩm. Điều đó mang lại cho chúng tôi 30 đợtSau đó, chúng tôi có thể chuyển từng lô dữ liệu sản phẩm sang phương thức 6 mới trên lớp 6, phương thức này đối với mỗi hàng dữ liệu trong tệp CSV sẽ cập nhật sản phẩm hiện có trong cơ sở dữ liệu của chúng tôi hoặc tạo một sản phẩm mới. Bằng cách này, chúng tôi sẽ chỉ thực hiện 30 truy vấn thay vì 300.000 nếu chúng tôi sử dụng phương pháp 0 (hãy nhớ rằng thực tế là 2 truy vấn cho mỗi lần sử dụng phương pháp này)Vậy upsert() hoạt động như thế nào?Tôi sẽ cho rằng bạn đang sử dụng MySQL, mặc dù nó hoạt động với các công cụ cơ sở dữ liệu khác Theo ví dụ của chúng tôi về cơ sở dữ liệu sản phẩm, được đơn giản hóa cho một lô chỉ 3 sản phẩm, đây là SQL sẽ được chạy
Như bạn có thể thấy, truy vấn bắt đầu bằng một câu lệnh 1 bình thường và nó sẽ cố gắng chèn tập giá trị dữ liệu đầu tiên vào bảng. Nếu thành công, nó sẽ loại bỏ sang tập tiếp theo. Tuy nhiên, nếu điều đó không thành công vì mã định danh duy nhất (trong ví dụ của chúng tôi, đó là "item_ref") đã tồn tại (i. hàng dữ liệu đã có trong bảng), thì nó sẽ bị bắt bởi phần 9 của truy vấn. SQL theo sau đó, trong trường hợp này là câu lệnh 0, sau đó sẽ được chạy. Điều này sẽ cập nhật hàng cơ sở dữ liệu hiện có với tập hợp các giá trị. Sau khi hoàn thành, nó sẽ chuyển sang bộ giá trị dữ liệu tiếp theoCòn hiệu suất của upert() thì sao?Để kiểm tra hiệu năng của phương thức 6 mới, tôi đã bắt đầu một dự án Laravel mới và tạo một lệnh thủ công đơn giản để thực hiện 3 bài kiểm tra - một bài sử dụng phương thức 2, một bài sử dụng phương thức 6 cho các hàng đơn lẻ và một bài sử dụng phương thức 6 với các lô Đối với mỗi bài kiểm tra, một mảng gồm 125.000 "sản phẩm" được ghi vào một bảng trống - đo thời gian cần thiết để hoàn thành. Sau đó, mọi mặt hàng trong mảng dữ liệu sản phẩm ban đầu được cập nhật với giá mới và thêm 25.000 sản phẩm khác. Dữ liệu thô được cập nhật này sau đó cũng được ghi vào cơ sở dữ liệu trong khi được hẹn giờ Tôi đã tạo một máy chủ mới trên Linode (với PHP 7. 4 & MySQL 8) và chạy lệnh thủ công 5 lần. Tôi tính trung bình số lần từ mỗi bài kiểm tra, kết quả như sau Bài kiểm tra 1 (phương pháp ____20)
Bài kiểm tra 2 (phương pháp ____16 - hàng số ít)
Bài kiểm tra 3 (phương pháp ____16 - hàng loạt)
Đúng như dự đoán, các thử nghiệm đầu tiên với phương pháp 0 là chậm nhất. Thử nghiệm thứ hai, sử dụng 6 cho từng sản phẩm một lần sẽ nhanh hơn một chút vì nó chỉ thực hiện 1 truy vấn cho từng sản phẩm, thay vì 2. Cuối cùng, thử nghiệm thứ ba, sử dụng 6 cho lô (5.000) sản phẩm nhanh hơn rất nhiều so với hai thử nghiệm còn lại. Trong các thử nghiệm của tôi, nó hoạt động nhanh hơn ~95% cho cả truy vấn 1 và truy vấn ______72 khi so sánh với 0Thật tuyệt, làm cách nào tôi có thể sử dụng upert()?Phương thức này có sẵn trong trình tạo truy vấn cơ sở dữ liệu Laravel và trình tạo truy vấn Eloquent. Nó chấp nhận 3 đối số 4giá trị $Đối số đầu tiên là một mảng gồm các mảng chứa dữ liệu sẽ được chèn/cập nhật - một mảng con cho mỗi hàng của mô hình/cơ sở dữ liệu Eloquent. Ví dụ
Nếu bạn đang sử dụng 6 trên một mô hình Eloquent sử dụng dấu thời gian, các thuộc tính 6 và 7 sẽ tự động được xử lý$uniqueByĐối số thứ hai mô tả cách xác định một hàng duy nhất Đây có thể là tên của một cột (được chuyển dưới dạng một chuỗi hoặc một mảng chứa một chuỗi đơn) hoặc nếu bạn có một khóa tổng hợp (hai hoặc nhiều cột được sử dụng để xác định duy nhất một hàng), tên của nhiều cột được chuyển . Ví dụ
Tất cả các công cụ cơ sở dữ liệu ngoại trừ SQL Server đều yêu cầu các cột trong đối số $uniqueBy phải có chỉ mục "chính" hoặc "duy nhất" cập nhật $Đối số thứ ba và đối số cuối cùng, là tùy chọn, xác định các cột sẽ được cập nhật nếu một hàng phù hợp đã tồn tại trong cơ sở dữ liệu. Điều này cho phép bạn bao gồm dữ liệu trong đối số 8 của mình sẽ chỉ được viết trên 1. Theo mặc định, tất cả các cột trong 8 của bạn đều được cập nhật, nhưng đây là một ví dụ nếu bạn muốn cung cấp đối số này
kết thúcTôi hy vọng bạn thấy điều này hữu ích - nếu muốn biết thêm, bạn có thể đọc tài liệu (mặc dù tôi đã đề cập đến mọi thứ và hơn thế nữa trong bài đăng trên blog này) hoặc xem lại các PR ban đầu trên GitHub. #34698, #34712 Tôi là @gbuckingham89 trên Twitter nếu bạn có bất kỳ câu hỏi nào về việc sử dụng 6 hoặc bất kỳ điều gì khác liên quan đến Laravel
Làm cách nào để cập nhật hoặc chèn vào Laravel?Về cơ bản, chúng tôi định vị bảng mà chúng tôi muốn cập nhật hoặc chèn bản ghi vào bằng cách sử dụng bảng(). Trong trường hợp này là bảng người dùng. Sau đó, chúng ta xâu chuỗi updateOrInsert() với nó, và trong updateOrInsert() chúng ta chuyển một mảng có điều kiện
Làm cách nào để cập nhật dữ liệu trong Laravel?Chúng tôi có thể cập nhật các bản ghi bằng cách sử dụng mặt tiền DB với phương thức cập nhật . Cú pháp của phương thức cập nhật như trong bảng sau. Chạy một câu lệnh cập nhật đối với cơ sở dữ liệu.
Trình tạo truy vấn trôi chảy trong Laravel là gì?Trình tạo truy vấn cơ sở dữ liệu của Laravel cung cấp giao diện thuận tiện, trôi chảy để tạo và chạy các truy vấn cơ sở dữ liệu . Nó có thể được sử dụng để thực hiện hầu hết các hoạt động cơ sở dữ liệu trong ứng dụng của bạn và hoạt động hoàn hảo với tất cả các hệ thống cơ sở dữ liệu được Laravel hỗ trợ.
Chúng ta nên cập nhật thông tin chi tiết về kết nối cơ sở dữ liệu trong Laravel ở đâu?Tệp cấu hình cơ sở dữ liệu là app/config/database. php . Trong tệp này, bạn có thể xác định tất cả các kết nối cơ sở dữ liệu của mình, cũng như chỉ định kết nối nào sẽ được sử dụng theo mặc định. |