JOINS và những điều cần biết trong cơ sở dữ liệu

Chúng tôi rất vui mừng được chia sẻ kiến thức sâu sắc về từ khóa Left outer join la gi để tối ưu hóa nội dung trang web và tiếp thị trực tuyến. Bài viết cung cấp phương pháp tìm kiếm, phân tích từ khóa và chiến lược hiệu quả. Cảm ơn sự quan tâm và hãy tiếp tục theo dõi để cập nhật kiến thức mới.

Lần trước tiên nghe đến JOIN, tôi đã nghĩ nó là cái gì đó cao siêu và hoành tráng lắm. Nhưng sau một hồi đọc rồi hiểu các kiểu về JOIN, thì mới có thể nhận ra rằng nó đó là những truy vấn tài liệu mà mình vẫn hay làm thường ngày, nhưng chỉ có điều là nó làm ngắn gọn và tăng tốc độ truy vấn lên thôi. “Chỉ có điều” ư? Không đâu! Làm ngắn gọn và tăng tốc độ truy vấn là xử lý được một vấn đề khá to lớn đấy.

Bạn Đang Xem: JOINS và những điều cần biết trong cơ sở dữ liệu

Là một mệnh đề trong SQL, sử dụng để kết nối tài liệu từ hai hay nhiều bảng trong cơ sở tài liệu lại với nhau. Khi bạn phải truy vấn các cột tài liệu từ nhiều bảng khác nhau để trả về trong cùng một tập trung chuyên sâu quả, bạn phải dùng JOIN, SQL sẽ tạo ra một bảng tạm thời chứa tài liệu kết quả từ JOIN.

Ta xét ví dụ sau: Một quan hệ rất đơn giản giữa các thực thể trong một dự án Ruby on Rails:

class User has_many :books end class Book belongs_to :user end

Thời điểm hiện tại, điều gì sẽ xẩy ra khi cố gắng nỗ lực để đã sở hữu được user cho từng book?

books = Book.all user_names = books.map book

Hãy nhìn vào console để xem điều gì xẩy ra:

Book Load (0.7ms) SELECT “books”.* FROM “books” User Load (0.2ms) SELECT “users”.* FROM “users” WHERE “users”.”id” = ? LIMIT ? [[“id”, 1], [“LIMIT”, 1]] User Load (0.1ms) SELECT “users”.* FROM “users” WHERE “users”.”id” = ? LIMIT ? [[“id”, 2], [“LIMIT”, 1]] User Load (0.1ms) SELECT “users”.* FROM “users” WHERE “users”.”id” = ? LIMIT ? [[“id”, 3], [“LIMIT”, 1]]

Dễ dàng thấy ra đây là vấn đề của N + 1 query. Truy vấn ban sơ của tất cả chúng ta (1 trong N +1) trả về collection có kích thước N, và đến lượt nó chạy một truy vấn cho từng một trong số chúng trong database (N trong N + 1).

Với việc sử dụng joins:

books = Book.all user_names = User.joins(:books)

Xem Thêm : Truyền Thuyết Về Icarus Là Gì, Icarus Và Mộng Tưởng Chinh Phục Bầu Trời

và console:

Book Load (0.7ms) SELECT “books”.* FROM “books” User Load (0.2ms) SELECT “users”.* FROM “users” INNER JOIN “books” ON “users”.”id” = “books”.”id”

Vậy là joins trong trường hợp này đã xử lý được vấn đề N+1 query. Đó mới chỉ là một trường hợp đơn giản ở trong Rails, ngoài ra join còn tồn tại giúp ích cho tất cả chúng ta rất nhiều nữa trong các truy vấn tài liệu. Trước tiên, ta cần phải ghi nhận có những loại join nào.

Tùy vào các tình huống khác nhau với những yêu cầu về tài liệu khác nhau, mà ta sẽ dùng các kiểu join khác nhau. Không có sự khác biệt nhiều giữa chúng, và cũng tương đối dễ hiểu, cơ bản có những loại như sau:

  1. INNER JOIN – trả về hàng khi có một sự phù hợp trong tất cả những bảng được join.

Ví dụ 1: Lấy ra những Orders của Customers, ta INNER JOIN 2 bảng Orders và Customers như sau:

SELECT Orders.OrderID, Customers.CustomerName, Orders.Orderdate FROM Orders INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID;

Trong số đó bảng Orders là bảng trái vì bên trái từ khóa INNER JOIN, Customers là bảng phải. Biểu thức sau từ khóa ON cụ thể Orders.CustomerID = Customers.CustomerID là biểu thức khớp nối.

Ví dụ 2: Lấy ra các đơn hàng kèm theo tên khách hàng và tên người ship đơn hàng đó, ta INNER JOIN ba bảng Orders, Customers, Shippers:

SELECT Orders.OrderID, Customers.CustomerName, Shippers.ShipperName FROM ((Orders INNER JOIN Customers ON Orders.CustomerID = Customers.CustomerID) INNER JOIN Shippers ON Orders.ShipperID = Shippers.ShipperID);

  1. LEFT JOIN
  • LEFT JOIN trả về tất cả bản ghi bảng bên trái, ngay cả những lúc không có sự phù hợp trong bảng bên phải, còn những bản ghi nào của bảng bên phải phù phù hợp với bảng trái thì tài liệu bản ghi này được dùng để làm kết phù hợp với bản ghi bảng trái, nếu không có tài liệu sẽ NULL.

SELECT Customers.CustomerName, Orders.OrderID FROM Customers LEFT JOIN Orders ON Customers.CustomerID = Orders.CustomerID ORDER BY Customers.CustomerName;

  1. RIGHT JOIN – trả về tất cả những hàng từ bảng bên phải, ngay cả những lúc không có sự phù hợp nào ở bảng bên trái.
  • Trường hợp này hoạt động giống với LEFT JOIN theo chiều trái lại.
  1. FULL JOIN – trả về hàng khi có một sự phù hợp trong một trong các bảng.
  • Xét tất cả những kết quả, với SQLite không tương trợ (có thể thay thế bằng LEFT JOIN kết phù hợp với UNION)

SELECT Customers.CustomerName, Orders.OrderID FROM Customers FULL OUTER JOIN Orders ON Customers.CustomerID = Orders.CustomerID ORDER BY Customers.CustomerName;

  1. SELF JOIN – được sử dụng để tham gia một bảng với chính nó như thể bảng đó là hai bảng, tạm thời thay tên ít nhất một bảng trong câu lệnh SQL.

Nếu muốn đọc để làm rõ hơn, các bạn cũng có thể qua đọc series các nội dung bài viết về join sql trên w3chool: https://www.w3schools.com/sql/sql_join.asp

  1. Ví dụ join 2 bảng

Xem Thêm : Bản chất tia X và cấu tạo – nguyên lý hoạt động của máy X-quang

Client.joins(‘LEFT OUTER JOIN addresses ON addresses.client_id = clients.id’) SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id

  1. Ví dụ join nhiều bảng cùng lúc

Category.joins(:posts => [{:comments => :guest}, :tags]) SELECT categories.* FROM categories INNER JOIN posts ON posts.category_id = categories.id INNER JOIN comments ON comments.post_id = posts.id INNER JOIN guests ON guests.comment_id = comments.id INNER JOIN tags ON tags.post_id = posts.id

  1. Ví dụ lấy ra những User cùng với bookmarks post của user đó:

User.joins(“LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = ‘Post’ AND bookmarks.user_id = users.id”) => SELECT “users”.* FROM “users” LEFT JOIN bookmarks ON bookmarks.bookmarkable_type = ‘Post’ AND bookmarks.user_id = users.id

Trong framework Ruby on Rails cung cấp những method query preload, eager_load, includes, references, joins, mỗi một phương pháp có cách hoạt động phù phù hợp với từng mục tiêu khác nhau. Việc không nắm rõ phương pháp hoạt động, ưu điểm, nhược điểm của những method này sẽ dẫn đến việc sử dụng sai trái, tốn tài nguyên cũng như vấn đề performance của ứng dụng. Để làm rõ hơn các method trên và để biết được phương pháp hoạt động và tốc độ xử lý của chúng, các bạn hãy tham khảo bảo viết: Tìm hiểu preload, eager_load, includes, references, and joins in Rails

Còn với vấn để mình đưa ra ở ví dụ đầu, khi sử dụng với preload, eager_load và includes thì nó sẽ như vậy này đây:

  1. preload

books = Book.all user_names = books.preload(:user).map book Book Load (0.3ms) SELECT “books”.* FROM “books” User Load (0.4ms) SELECT “users”.* FROM “users” WHERE “users”.”id” IN (1, 2, 3)

  1. eager_load

user_names = books.eager_load(:user).map book #=> SQL (0.4ms) SELECT “books”.”id” AS t0_r0, “books”.”title” AS t0_r1, “books”.”author” AS t0_r2, #=> “books”.”books_id” AS t0_r3, “books”.”user_id” AS t0_r4, “books”.”created_at” AS t0_r5, #=> “books”.”updated_at” AS t0_r6, “users”.”id” AS t1_r0, “users”.”name” AS t1_r1, #=> “users”.”created_at” AS t1_r2, “users”.”updated_at” AS t1_r3 FROM “books” #=> LEFT OUTER JOIN “users” ON “users”.”id” = “books”.”user_id”

  1. includes

books.includes(:user).where(‘users.name=”Guava”‘) #=> #=> SELECT “books”.”id” AS t0_r0, “books”.”title” AS t0_r1, #=> “books.”author” AS t0_r2, “books”.”books_id” AS t0_r3, #=> “books”.”user_id” AS t0_r4, “books”.”created_at” AS t0_r5, #=> “books”.”updated_at” AS t0_r6, “users”.”id” AS t1_r0, #=> “users”.”name” AS t1_r1, “users”.”created_at” AS t1_r2, #=> “users”.”updated_at” AS t1_r3 FROM “books” #=> LEFT OUTER JOIN “users” ON “users”.”id”= “books”.”user_id” #=> WHERE (users.name=”Guava”)

https://www.w3schools.com/sql/sql_join.asp

http://guides.rubyonrails.org/active_record_querying.html#joining-tables

https://viblo.asia/p/join-hay-khong-join-mot-hanh-dong-includes-bWrZnNwwZxw

https://viblo.asia/p/tim-hieu-preload-eager-load-includes-references-and-joins-in-rails-roavrwPXGRM

You May Also Like

About the Author: v1000