2010-11-10 38 views
7

Cơ sở dữ liệu dấu trang (đã được đơn giản hóa). Tôi nghĩ rằng nó sẽ làm cho tinh thần để tổ chức các bảng một cách logic, như vậy:Cách tối ưu để tham gia ba bảng trong SQLite

Bookmarks (id, title, url; basically external data) 
+------+------------+-----+ 
| suid | Title | ... | 
+------+------------+-----+ 

User (user-specific data: favorites, ratings, etc) 
+------+------------+-----+ 
| suid | IsFavorite | ... | 
+  + (0 or 1) +  + 
+------+------------+-----+ 

History (last used, use count etc) 
+------+------------+-----+ 
| suid | LastUsed | ... | 
+  +(TDateTime) +  + 
+------+------------+-----+ 

('suid' là ID duy nhất, nguyên sơ cấp key)

Từ bookmark gắn cờ là yêu thích tôi cần phải chọn N được sử dụng gần đây nhất (để điền trình đơn vào thời gian chạy khi thuận tiện).

SELECT Bookmarks.suid, Title from Bookmarks 
    INNER JOIN User USING (suid) 
    INNER JOIN History USING (suid) 
    WHERE IsFavorite = 1 
    ORDER BY LastUsed DESC 
    LIMIT 15; 

Tuyên bố hoạt động và có vẻ dễ đọc, nhưng tối ưu? Bảng Dấu trang nhằm mục đích giữ trung bình 20-50 nghìn bản ghi (nghĩa là không phải trình quản lý dấu trang trình duyệt chuẩn của bạn :-) Ứng dụng sẽ thực thi 3 hoặc 4 câu lệnh tương tự khi khởi động để điền các điều khiển. Tất cả các trường được sử dụng trong ví dụ đều được lập chỉ mục.

Tôi tự dạy SQL và đưa ra mã trên, nhưng có lẽ tôi đang xem một cú pháp hoặc thành ngữ có thể cải thiện nó?

+0

Nếu chỉ báo ưa thích được lưu trữ trong bảng người dùng, điều đó sẽ suy ra rằng tất cả dấu trang được liên kết với người dùng là mục yêu thích - cần phải ở cấp đánh dấu hoặc tôi hiểu sai mục đích. –

+0

Tôi có xu hướng giải thích quá mức trong các câu hỏi của mình, vì vậy tôi đã pha chế một ví dụ đơn giản về xương trần để tránh điều đó. Bảng đánh dấu chính sẽ được cập nhật định kỳ. Trong quá trình cập nhật, tôi không muốn chạm vào bất kỳ dữ liệu nào mà người dùng đã nhập, như xếp hạng, đánh dấu là mục yêu thích, v.v. Tương tự như vậy, một số người dùng có thể không muốn duy trì lịch sử, trong trường hợp đó ứng dụng chỉ có thể xóa hoặc xóa toàn bộ bảng lịch sử. (Hoặc, có lẽ cái tên 'Người dùng' là gây hiểu lầm. Nó không phải là một bảng cho dữ liệu tài khoản người dùng, nhưng đối với các điểm dữ liệu được người dùng nhập vào. Đó là ứng dụng dành cho máy tính để bàn một người dùng.) –

Trả lời

4

Không thể (hoặc ít nhất rất, rất khó) để đoán từ SQL thô chính xác như thế nào cơ sở dữ liệu sẽ đi về đáp ứng các truy vấn. Vì lý do đó, bạn cần sử dụng GIẢI THÍCH để tìm hiểu xem SQLite sẽ thực sự nhận dữ liệu như thế nào. Và lưu ý rằng kế hoạch thực hiện mà nó tạo ra sẽ khác nhau tùy thuộc vào lượng dữ liệu trong mỗi bảng và dữ liệu "trông" như thế nào (về số lượng các giá trị khác nhau được tìm thấy trong các cột được lập chỉ mục). Vì vậy, hãy đảm bảo đánh dấu cơ sở dữ liệu thử nghiệm của bạn bằng dữ liệu thực tế. Khi bạn thử GIẢI THÍCH, tôi nghĩ có khả năng bạn sẽ thấy rằng SQLite đang nối các bảng lại với nhau trước khi tham gia 15 trận đấu hàng đầu, điều này sẽ không tối ưu nếu đúng. Nếu điều đó hóa ra là như vậy, bạn có thể thử một cái gì đó như:

SELECT Bookmarks.suid, Title from Bookmarks 
    INNER JOIN User USING (suid) 
    WHERE IsFavorite = 1 
    AND suid IN (SELECT suid FROM History ORDER BY LastUsed DESC LIMIT 15); 

Nhưng, một lần nữa, không nên cố gắng cho đến khi bạn đã nhìn thấy từ giải thích rằng SQLite là nhận được dữ liệu một cách không tối ưu .

0

Có vẻ ổn với tôi. Bạn có thể đã biết điều này nhưng bạn có thể điều tra truy vấn của mình bằng cách sử dụng từ khóa giải nghĩa (http://www.sqlite.org/lang_explain.html) nếu bạn muốn điều chỉnh thêm.

Chúc mừng!

0

Bạn có thể sử dụng từ khóa GIẢI THÍCH như đã nói, nhưng có một số cách khác để cải thiện nó. Có một trang web với một số thông tin ... kiểm tra nó ra Clickin 'here để tìm hiểu thêm về nó ... chúc may mắn!

Các vấn đề liên quan