Cách hiệu quả nhất để lưu trữ các thẻ trong cơ sở dữ liệu là gì?


138

Tôi đang triển khai một hệ thống gắn thẻ trên trang web của mình tương tự như sử dụng stackoverflow, câu hỏi của tôi là - cách hiệu quả nhất để lưu trữ thẻ để chúng có thể được tìm kiếm và lọc?

Ý tưởng của tôi là thế này:

Table: Items
Columns: Item_ID, Title, Content

Table: Tags
Columns: Title, Item_ID

Đây có phải là quá chậm? Có cách nào tốt hơn?


2
Đã hỏi trước đó: stackoverflow.com/questions/20856/
Mạnh

1
Kể từ năm 2016, hãy sử dụng Solr hoặc Elaticsearch
Charles L.

Câu trả lời:


190

Một mục sẽ có nhiều thẻ. Và một thẻ sẽ thuộc về nhiều mặt hàng. Điều này ngụ ý với tôi rằng bạn hoàn toàn có thể cần một bảng trung gian để vượt qua trở ngại nhiều-nhiều.

Cái gì đó như:

Bảng:
Cột Mục : Item_ID, Item_Title, Nội dung

Bảng: Thẻ
Cột: Tag_ID, Tag_Title

Bảng: Cột_Tags
Cột: Item_ID, Tag_ID

Có thể là ứng dụng web của bạn cực kỳ phổ biến và cần phải chuẩn hóa trên đường, nhưng nó vô tình làm vấy bẩn vùng biển quá sớm.



nếu có một số thứ như taggroup, làm thế nào để xử lý nó, ví dụ như các thẻ được nhóm thành các danh mục, ví dụ: Ngôn ngữ lập trình: c #, vb, Pearl. HĐH: windows7, dos, linux, v.v.
Thunder

4
@Thunder: giả sử rằng một thẻ chỉ có thể thuộc về một danh mục, tôi sẽ tạo bảng TagC Category bao gồm category_id và category_name. Từ đó, tôi sẽ thêm một trường category_id vào bảng Tags và thực hiện nối vào đó.
Simon Khăne

114

Bạn nên đọc các bài đăng trên blog của Philipp Keller về việc gắn thẻ các lược đồ cơ sở dữ liệu. Anh ta thử một vài và báo cáo kết quả của mình, cả về mặt dễ dàng xây dựng các truy vấn phổ biếnvề hiệu suất . Số lượng thẻ, số lượng mục được gắn thẻ và số lượng thẻ cho mỗi mục là tất cả các yếu tố. Các bài viết là từ năm 2005; Tôi không biết về bất kỳ cập nhật nào kể từ đó.


19
Tôi nghĩ rằng đây là câu trả lời tốt nhất. Nó dựa trên các bài kiểm tra và nghiên cứu thực tế thay vì giả định như hầu hết các câu trả lời khác.
Cristian Vrabie

4
Các liên kết trong câu trả lời dường như không hoạt động. Tìm thấy một bản sao tại vtidter.blogspot.be/2014/02/database-schema-for-tags.html
Herreman

8

Trên thực tế tôi tin rằng việc không chuẩn hóa bảng thẻ có thể là một cách tốt hơn về phía trước, tùy thuộc vào quy mô.

Bằng cách này, bảng thẻ chỉ đơn giản là có tagid, itemid, tagname.

Bạn sẽ nhận được các tên thẻ trùng lặp, nhưng nó làm cho việc thêm / xóa / chỉnh sửa thẻ cho các mục cụ thể RẤT NHIỀU. Bạn không phải tạo thẻ mới, xóa phân bổ thẻ cũ và phân bổ lại thẻ mới, bạn chỉ cần chỉnh sửa tên thẻ.

Để hiển thị danh sách các thẻ, bạn chỉ cần sử dụng DISTINCT hoặc GROUP BY và tất nhiên bạn cũng có thể đếm số lần một thẻ được sử dụng dễ dàng.


4

Nếu bạn không phiền khi sử dụng một chút nội dung không chuẩn, Postgres phiên bản 9.4 trở lên có tùy chọn lưu trữ bản ghi của mảng văn bản JSON loại.

Lược đồ của bạn sẽ là:

Table: Items
Columns: Item_ID:int, Title:text, Content:text

Table: Tags
Columns: Item_ID:int, Tag_Title:text[]

Để biết thêm thông tin, hãy xem bài đăng tuyệt vời này của Josh Berkus: http://www.databaseoup.com/2015/01/tag-all-things.html

Có nhiều tùy chọn khác nhau được so sánh kỹ lưỡng về hiệu suất và một trong những gợi ý ở trên là tổng thể tốt nhất.


2

Tôi khuyên bạn nên sử dụng bảng thứ ba trung gian để lưu trữ thẻ <=> liên kết các mục, vì chúng tôi có mối quan hệ nhiều-nhiều giữa các thẻ và mục, tức là một mục có thể được liên kết với nhiều thẻ và một thẻ có thể được liên kết với nhiều mục. HTH, Van.


1

Bạn thực sự không thể nói về sự chậm chạp dựa trên dữ liệu bạn cung cấp trong một câu hỏi. Và tôi không nghĩ bạn thậm chí nên lo lắng quá nhiều về hiệu suất ở giai đoạn phát triển này. Nó được gọi là tối ưu hóa sớm .

Tuy nhiên, tôi khuyên bạn nên bao gồm cột Tag_ID trong bảng Thẻ. Đó thường là một thực hành tốt mà mỗi bảng có một cột ID.


1

Nếu không gian sẽ là một vấn đề, hãy có Thẻ bảng thứ 3 (Tag_Id, Tiêu đề) để lưu trữ văn bản cho thẻ và sau đó thay đổi bảng Thẻ của bạn thành (Tag_Id, Item_Id). Hai giá trị này cũng sẽ cung cấp một khóa chính tổng hợp duy nhất.


0

Các mục nên có trường "ID" và Thẻ phải có trường "ID" (Khóa chính, được nhóm).

Sau đó, tạo một bảng trung gian của ItemID / TagID và đặt " Chỉ mục hoàn hảo " vào đó.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.