Tôi tin rằng bạn sẽ thấy thú vị với bài đăng blog này: Tags: Các lược đồ cơ sở dữ liệu
Vấn đề: Bạn muốn có một lược đồ cơ sở dữ liệu nơi bạn có thể gắn thẻ dấu trang (hoặc một bài đăng trên blog hoặc bất cứ thứ gì) với bao nhiêu thẻ tùy thích. Sau đó, bạn muốn chạy các truy vấn để ràng buộc các dấu trang vào một tổ hợp hoặc giao điểm của các thẻ. Bạn cũng muốn loại trừ (giả sử: trừ) một số thẻ khỏi kết quả tìm kiếm.
Giải pháp “MySQLicious”
Trong giải pháp này, lược đồ chỉ có một bảng, nó không được chuẩn hóa. Loại này được gọi là “giải pháp MySQLicious” vì MySQLicious nhập dữ liệu del.icio.us vào một bảng có cấu trúc này.
Truy vấn Intersection (AND) cho “search + webservice + semweb”:
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags LIKE "%semweb%"
Union (HOẶC) Truy vấn cho “search | webservice | semweb”:
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
OR tags LIKE "%webservice%"
OR tags LIKE "%semweb%"
Truy vấn trừ cho “search + webservice-semweb”
SELECT *
FROM `delicious`
WHERE tags LIKE "%search%"
AND tags LIKE "%webservice%"
AND tags NOT LIKE "%semweb%"
Giải pháp "Scuttle"
Scuttle sắp xếp dữ liệu của nó trong hai bảng. Bảng “scCategories” đó là bảng “thẻ” và có khóa ngoại cho bảng “đánh dấu”.
Truy vấn Intersection (AND) cho “bookmark + webservice + semweb”:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
HAVING COUNT( b.bId )=3
Đầu tiên, tất cả các tổ hợp thẻ dấu trang đều được tìm kiếm, trong đó thẻ là “dấu trang”, “dịch vụ web” hoặc “semweb” (c.category IN ('dấu trang', 'dịch vụ web', 'semweb')), sau đó chỉ là dấu trang đã tính đến tất cả ba thẻ được tìm kiếm (HAVING COUNT (b.bId) = 3).
Union (HOẶC) Truy vấn cho “bookmark | webservice | semweb”:
Chỉ cần bỏ đi mệnh đề HAVING và bạn đã có union:
SELECT b.*
FROM scBookmarks b, scCategories c
WHERE c.bId = b.bId
AND (c.category IN ('bookmark', 'webservice', 'semweb'))
GROUP BY b.bId
Trừ (Loại trừ) Truy vấn cho “bookmark + webservice-semweb”, nghĩa là: bookmark VÀ webservice VÀ KHÔNG phải semweb.
SELECT b. *
FROM scBookmarks b, scCategories c
WHERE b.bId = c.bId
AND (c.category IN ('bookmark', 'webservice'))
AND b.bId NOT
IN (SELECT b.bId FROM scBookmarks b, scCategories c WHERE b.bId = c.bId AND c.category = 'semweb')
GROUP BY b.bId
HAVING COUNT( b.bId ) =2
Bỏ đi COUNTING COUNT sẽ dẫn đến Truy vấn cho “bookmark | webservice-semweb”.
Giải pháp "Toxi"
Toxi đã đưa ra cấu trúc ba bảng. Qua bảng “sơ đồ thẻ”, các dấu trang và các thẻ có liên quan n-to-m. Mỗi thẻ có thể được sử dụng cùng với các dấu trang khác nhau và ngược lại. Lược đồ DB này cũng được sử dụng bởi wordpress. Các truy vấn khá giống như trong giải pháp "scuttle".
Truy vấn Intersection (AND) cho “bookmark + webservice + semweb”
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
HAVING COUNT( b.id )=3
Union (HOẶC) Truy vấn cho “bookmark | webservice | semweb”
SELECT b.*
FROM tagmap bt, bookmark b, tag t
WHERE bt.tag_id = t.tag_id
AND (t.name IN ('bookmark', 'webservice', 'semweb'))
AND b.id = bt.bookmark_id
GROUP BY b.id
Trừ (Loại trừ) Truy vấn cho “bookmark + webservice-semweb”, nghĩa là: bookmark VÀ webservice VÀ KHÔNG phải semweb.
SELECT b. *
FROM bookmark b, tagmap bt, tag t
WHERE b.id = bt.bookmark_id
AND bt.tag_id = t.tag_id
AND (t.name IN ('Programming', 'Algorithms'))
AND b.id NOT IN (SELECT b.id FROM bookmark b, tagmap bt, tag t WHERE b.id = bt.bookmark_id AND bt.tag_id = t.tag_id AND t.name = 'Python')
GROUP BY b.id
HAVING COUNT( b.id ) =2
Bỏ đi COUNTING COUNT sẽ dẫn đến Truy vấn cho “bookmark | webservice-semweb”.