Ok, đây là cách tôi thấy nó hoạt động.
Tôi có cùng một vấn đề với MongoDB. MongoDB "cung cấp" khả năng tìm kiếm nhưng cũng giống như MySQL, bạn không bao giờ nên sử dụng chúng trừ khi bạn muốn bị nghẹt thở với IO, các vấn đề về CPU và bộ nhớ và buộc phải sử dụng nhiều máy chủ hơn để đối phó với chỉ mục của bạn so với bình thường.
Toàn bộ ý tưởng nếu sử dụng Sphinx (hoặc một công nghệ tìm kiếm khác) là giảm chi phí trên mỗi máy chủ bằng cách có một trình tìm kiếm chỉ mục hoạt động hiệu quả.
Sphinx tuy nhiên không phải là một công cụ lưu trữ. Việc truy vấn các mối quan hệ chính xác giữa các bảng không đơn giản như vậy, họ đã khắc phục điều này một chút với SphinxQL nhưng do bản chất của chỉ mục toàn văn nên nó vẫn không thực hiện một phép nối tích hợp như bạn sẽ nhận được trong MySQL.
Thay vào đó, tôi sẽ lưu trữ các mối quan hệ trong MySQL nhưng có chỉ mục "người dùng" trong Sphinx.
Trong trang web của tôi, cá nhân tôi có 2 chỉ mục:
- chính (chứa người dùng, video, kênh và danh sách phát)
- trợ giúp (tìm kiếm hệ thống trợ giúp)
Đây là những đồng bằng được cập nhật mỗi phút một lần. Vì các chỉ mục thời gian thực đôi khi vẫn còn đang thử nghiệm và cá nhân tôi đã thấy các vấn đề với tỷ lệ chèn / xóa cao mà tôi giữ cho các bản cập nhật delta. Vì vậy, tôi sẽ sử dụng chỉ mục delta để cập nhật các đối tượng có thể tìm kiếm chính trên trang web của mình vì điều này tốn ít tài nguyên hơn và hiệu quả hơn so với chỉ mục thời gian thực (từ các thử nghiệm của riêng tôi).
Hãy lưu ý inorder để xử lý xóa và những gì không phải bộ sưu tập Sphinx của bạn thông qua delta, bạn sẽ cần một danh sách tiêu diệt và một số bộ lọc nhất định cho chỉ mục delta của bạn. Đây là một ví dụ từ chỉ mục của tôi:
source main_delta : main
{
sql_query_pre = SET NAMES utf8
sql_query_pre =
sql_query = \
SELECT id, deleted, _id, uid, listing, title, description, category, tags, author_name, duration, rating, views, type, adult, videos, UNIX_TIMESTAMP(date_uploaded) AS date_uploaded \
FROM documents \
WHERE id>( SELECT max_doc_id FROM sph_counter WHERE counter_id=1 ) OR update_time >( SELECT last_index_time FROM sph_counter WHERE counter_id=1 )
sql_query_killlist = SELECT id FROM documents WHERE update_time>=( SELECT last_index_time FROM sph_counter WHERE counter_id=1 ) OR deleted = 1
}
Quá trình này xử lý các thao tác xóa và bổ sung mỗi phút một lần, tương đối nhiều trong thời gian thực đối với một ứng dụng web thực.
Vì vậy, bây giờ chúng ta biết cách lưu trữ các chỉ mục của mình. Tôi cần nói về các mối quan hệ. Sphinx (mặc dù nó có SphinxQL) sẽ không thực hiện các phép nối tích hợp trên toàn bộ dữ liệu vì vậy cá nhân tôi khuyên bạn nên thực hiện mối quan hệ bên ngoài Sphinx, không chỉ vậy mà như tôi đã nói bảng mối quan hệ này sẽ có tải cao nên đây là điều có thể ảnh hưởng đến Chỉ số nhân sư.
Tôi sẽ thực hiện một truy vấn để chọn ra tất cả các id và sử dụng tập hợp các id đó, sử dụng phương pháp "bộ lọc" trên API sphinx để lọc chỉ mục chính xuống các id tài liệu cụ thể. Sau khi hoàn tất, bạn có thể tìm kiếm trong Sphinx như bình thường. Đây là phương pháp hiệu quả nhất mà tôi đã tìm thấy cho đến nay để giải quyết vấn đề này.
Điều quan trọng cần nhớ mọi lúc là Sphinx là công nghệ tìm kiếm trong khi MySQL là công nghệ lưu trữ. Hãy ghi nhớ điều đó và bạn sẽ ổn.
Chỉnh sửa
Như @ N.B đã nói (mà tôi đã bỏ qua trong câu trả lời của mình) Sphinx có SphinxSE. Mặc dù nguyên thủy và vẫn đang trong giai đoạn thử nghiệm của quá trình phát triển (giống như các chỉ mục thời gian thực), nó cung cấp một bộ lưu trữ kiểu MyISAM / InnoDB thực tế cho Sphinx. Điều này thật tuyệt. Tuy nhiên, có những lưu ý (như với bất cứ điều gì):
- Ngôn ngữ là nguyên thủy
- Các phép nối là nguyên thủy
Tuy nhiên, nó có thể / có thể thực hiện công việc mà bạn đang tìm kiếm, vì vậy hãy chắc chắn xem xét nó.