Cách tiếp cận dễ nhất mà tôi đoán sẽ là:
- Tạo hai bảng mới:
keywords
(id, word) vàkeywords_comments
(keyword_id, comment_id, count)-
keywords
lưu một id duy nhất và từ khóa bạn tìm thấy trong văn bản -
keywords_comments
lưu trữ một hàng cho mỗi kết nối giữa mỗi nhận xét có chứa từ khóa đó. Trongcount
bạn sẽ lưu số lần từ khóa này xuất hiện trong nhận xét. Hai cột keyword_id + comment_id cùng nhau tạo thành một khóa chính duy nhất hoặc trực tiếp.
-
- Truy xuất tất cả các nhận xét từ cơ sở dữ liệu
- Phân tích cú pháp thông qua tất cả các nhận xét và phân chia theo các ký tự không phải (hoặc các ranh giới khác)
- Viết các mục này vào bảng của bạn
Ví dụ
Bạn có hai nhận xét sau:
Bây giờ bạn sẽ lặp lại cả hai và chia chúng theo các ký tự không phải. Điều này sẽ dẫn đến các từ viết thường sau đây cho mỗi văn bản:- Văn bản đầu tiên:xin chào, thế nào, đang, bạn- Văn bản thứ hai:wow, xin chào, tôi, tên, là, stefan
Ngay sau khi bạn đã phân tích cú pháp một trong các văn bản này, bạn đã có thể chèn lại nó vào cơ sở dữ liệu. Tôi đoán bạn không muốn tải 100.000 bình luận vào RAM.
Vì vậy, nó sẽ diễn ra như sau:
- Phân tích cú pháp văn bản đầu tiên và lấy các từ khóa ở trên
- Viết từng từ khóa vào
keywords
tabke nếu nó vẫn chưa có - Đặt một tham chiếu từ từ khóa đến nhận xét (
keywords_comments
) và đặt số lượng chính xác (trong ví dụ của chúng tôi, mỗi từ chỉ xuất hiện một lần trong mỗi văn bản, bạn phải đếm số đó). - Phân tích cú pháp văn bản thứ hai
- …
Cải thiện nhỏ
Một cải tiến rất dễ dàng mà bạn có thể phải sử dụng cho 100.000 nhận xét, đó là sử dụng biến đếm hoặc thêm trường mới has_been_analyzed cho mỗi nhận xét. Sau đó, bạn có thể đọc nhận xét của họ bằng nhận xét từ cơ sở dữ liệu.
Tôi thường sử dụng các biến đếm khi tôi đọc dữ liệu theo chiều kim đồng hồ và biết rằng dữ liệu không thể không thay đổi so với hướng tôi đang bắt đầu (tức là nó sẽ luôn nhất quán cho đến thời điểm hiện tại của tôi). Sau đó, tôi làm một cái gì đó như:
SELECT * FROM table ORDER BY created ASC LIMIT 0, 100
SELECT * FROM table ORDER BY created ASC LIMIT 100, 100
SELECT * FROM table ORDER BY created ASC LIMIT 200, 100
…
Hãy cân nhắc rằng điều này chỉ hoạt động nếu chúng ta biết chắc chắn rằng không có ngày tháng nào được thêm vào tại một địa điểm mà chúng ta nghĩ rằng chúng ta đã đọc. Ví dụ. sử dụng DESC
sẽ không hoạt động, vì có thể có dữ liệu được chèn vào. Sau đó, toàn bộ phần bù sẽ bị phá vỡ và chúng tôi sẽ đọc một bài báo hai lần và không bao giờ đọc bài báo mới.
Nếu bạn không thể đảm bảo rằng biến đếm bên ngoài vẫn nhất quán, bạn có thể thêm trường mới đã phân tích mà bạn đặt thành true ngay sau khi bạn đọc nhận xét. Sau đó, bạn luôn có thể thấy bình luận nào đã được đọc và bình luận nào chưa. Khi đó, một truy vấn SQL sẽ giống như sau:
SELECT * FROM table WHERE analyzed = 0 LIMIT 100 /* Reading chunks of 100 */
Điều này hoạt động miễn là bạn không song song khối lượng công việc (với nhiều máy khách hoặc luồng). Nếu không, bạn sẽ phải đảm bảo rằng việc đọc + cài đặt true là nguyên tử (được đồng bộ hóa).