Chà, truy vấn duy nhất có thể hoạt động cho đến nay là của Simon ... nhưng đó là mức cần thiết thực sự - một truy vấn khó chịu phức tạp (2 truy vấn con với 2 liên kết!) Cho một điều đơn giản đến mức bạn cần đặt tiền thưởng? :-) Và nếu bạn có hơn 1000 người dùng, truy vấn sẽ rất chậm - hãy nhớ rằng, nó là bậc hai và do sự hợp nhất trong các truy vấn con, nên hầu như không có chỉ mục nào được sử dụng!
Tôi khuyên bạn nên suy nghĩ lại thiết kế và cho phép 2 hàng trùng lặp để có một tình bạn:
id Person1 Person2 status
1 1 2 friend
2 2 1 friend
3 1 3 friend
4 3 1 friend
Bạn có thể nghĩ điều đó không hiệu quả nhưng việc đơn giản hóa sau sẽ cho phép viết lại truy vấn thành các phép nối đơn giản:
select f1.Person2 as common_friend
from friends as f1 join friends as f2
using (Person2)
where f1.Person1 = '$id1' and f2.Person1 = '$id2'
and f1.status = 'friend' and f2.status = 'friend'
mà sẽ nhanh như địa ngục! (Đừng quên thêm chỉ số cho Person1,2.) Tôi đã khuyên một cách đơn giản hóa tương tự (viết lại truy vấn con để kết hợp) trong cấu trúc dữ liệu rất khó chịu khác và nó đã tăng tốc truy vấn từ vĩnh cửu đến chớp nhoáng!
Vì vậy, những gì có thể trông như một chi phí lớn (2 hàng cho một tình bạn) thực sự là một tối ưu hóa lớn :-)
Ngoài ra, nó sẽ làm cho các truy vấn như "tìm tất cả bạn bè của X" dễ dàng hơn nhiều. Và sẽ không cần chi thêm tiền thưởng :-)