2010-05-21 19 views
23

Relatedcách để triển khai thẻ - ưu và nhược điểm của mỗi

Sử dụng SO làm ví dụ, cách hợp lý nhất để quản lý thẻ nếu bạn dự đoán họ sẽ thay đổi thường xuyên là gì?

Cách 1: Nghiêm túc denormalized (dấu phẩy phân cách)

 
table posts 
+--------+-----------------+ 
| postId | tags   | 
+--------+-----------------+ 
| 1 | c++,search,code | 

Đây thẻ được Comma delimited.

Ưu điểm: Thẻ được truy lục cùng một lúc bằng một truy vấn select. Việc cập nhật thẻ rất đơn giản. Dễ dàng và rẻ tiền để cập nhật.

Nhược điểm: Phân tích cú pháp bổ sung khi truy xuất thẻ, khó đếm số lượng bài đăng sử dụng thẻ nào.

(cách khác, nếu giới hạn trong một cái gì đó giống như 5 thẻ)

 
table posts 
+--------+-------+-------+-------+-------+-------+ 
| postId | tag_1 | tag_2 | tag_3 | tag_4 | tag_5 | 
+--------+-------+-------+-------+-------+-------+ 
| 1 | c++ |search | code |  |  | 

Way 2: "Hơi bình thường" (bảng riêng biệt, không có ngã tư)

 
table posts 
+--------+-------------------+ 
| postId | title    | 
+--------+-------------------+ 
| 1 | How do u tag?  | 

table taggings 
+--------+---------+ 
| postId | tagName | 
+--------+---------+ 
| 1 | C++  | 
| 1 | search | 

Ưu: Dễ dàng để xem số lượng thẻ (count(*) from taggings where tagName='C++').

Nhược điểm: tagName có thể sẽ được lặp lại nhiều lần, nhiều lần.

Way 3: Các bé mát mẻ của (bình thường với bàn giao)

 
table posts 
+--------+---------------------------------------+ 
| postId | title         | 
+--------+---------------------------------------+ 
| 1 | Why is a raven like a writing desk? | 

table tags 
+--------+---------+ 
| tagId | tagName | 
+--------+---------+ 
| 1 | C++  | 
| 2 | search | 
| 3 | foofle | 

table taggings 
+--------+---------+ 
| postId | tagId | 
+--------+---------+ 
| 1 | 1  | 
| 1 | 2  | 
| 1 | 3  | 

Ưu:

  • Không lặp lại tên thẻ.
  • Nhiều cô gái khác thích bạn.

Nhược điểm: Đắt tiền hơn để thay đổi thẻ so với cách # 1.

+0

Tôi sẽ gửi email/twitter người đã phải quản lý thẻ trước bạn. Giống như Jeff Atwood hoặc một trong những nhà phát triển SO khác. Họ có thể đưa ra một số hiểu biết. –

+6

âm thanh với tôi như bạn vừa trả lời câu hỏi. Vì vậy, chỉ cần chọn một trong đó phù hợp nhất với yêu cầu của bạn. Nếu bạn muốn các cô gái thích bạn thì hãy đi # 3. – mdma

+0

Nhiều cô gái sẽ thích bạn, eh? Tôi thích sự lựa chọn đó! – Tarka

Trả lời

23

Các giải pháp này được gọi là mysqlicious, scuttletoxi.

This article so sánh các lợi ích và hạn chế của từng loại.

+0

Ah vâng, tôi chỉ tìm thấy điều này. Rất hữu ích! – bobobobo

+0

Dường như liên kết bị hỏng. – Diederik

+0

@Diederik: xem ngay bây giờ – Quassnoi

0

Cá nhân tôi ưu tiên giải pháp # 3.

Tôi không đồng ý rằng giải pháp # 1 dễ dàng hơn để duy trì. Hãy suy nghĩ về tình huống mà bạn phải thay đổi tên của một thẻ.

Giải pháp # 1:

UPDATE posts SET tag = REPLACE(tag, "oldname", "newname") WHERE tag LIKE("%oldname%") 

Giải pháp # 3:

UPDATE tags SET tag = "newname" WHERE tag = "oldname" 

Đầu tiên là cách nặng hơn.

Ngoài ra, bạn phải đối phó với các dấu phẩy khi xóa thẻ (OK, nó dễ dàng thực hiện nhưng vẫn còn, khó khăn hơn mà chỉ xóa một dòng trong bảng taggings)

Đối với giải pháp # 2 ... không phải là cá cũng không cầm

1

tôi sẽ lập luận rằng có một giải pháp thứ tư mà là một biến thể của giải pháp thứ ba của bạn:

Create Table Posts 
(
    id ... 
    , title ... 
) 
Create Table Tags 
(
    name varchar(30) not null primary key 
    , ... 
) 

Create Table PostTags 
(
    PostId ... 
    , TagName varchar(30) not null 
    , Constraint FK_PostTags_Posts 
     Foreign Key (PostId) 
     References Posts(Id) 
    , Constraint FK_PostTags_Tags 
     Foreign Key (TagName) 
     References Tags(Name) 
     On Update Cascade 
     On Delete Cascade 
) 

Chú ý rằng tôi đang sử dụng tên thẻ là khóa chính của bảng thẻ. Bằng cách này, bạn có thể lọc trên các thẻ nhất định mà không cần tham gia thêm vào bảng Thẻ. Ngoài ra, nếu bạn thay đổi tên thẻ, nó sẽ cập nhật tên trong bảng PostTags. Nếu thay đổi tên thẻ là một sự xuất hiện hiếm, thì đây không phải là vấn đề. Nếu thay đổi tên thẻ là sự xuất hiện phổ biến, thì tôi sẽ đi với giải pháp thứ ba của bạn, nơi bạn sử dụng khóa thay thế để tham chiếu thẻ.

+0

@Thomas: điều này giống như 'scuttle', khó quản lý hơn nhiều. Khả năng viết 'UPDATE Thẻ SET TagName = 'newtag' WHERE TagName = 'oldtag'' thay vì' UPDATE PostTags SET TagName =' newtag 'WHERE TagName =' oldtag'' không thực sự đáng giá. – Quassnoi

+0

@Quassnoi - Với Cập nhật Cascade, bạn chỉ cần viết 'Cập nhật Thẻ Set Name = 'NewName' Tên Name = 'OldName''. Không khó quản lý điều đó nếu bạn sử dụng khóa thay thế. Câu hỏi thực sự là liệu lợi ích của việc tránh tham gia thêm có lớn hơn tần suất mà bạn đang thay đổi tên thẻ hiện tại hay không. Vì tôi cho rằng sau này là không thường xuyên, lợi ích hiệu suất có lẽ đáng giá. – Thomas

+0

@Thomas: một lần nữa, nó khác với cách 2 ('scuttle') ngoại trừ việc có thêm một bảng (' Thẻ ') không phục vụ mục đích gì? – Quassnoi

0

Tôi nghĩ rằng SO sử dụng giải pháp # 1. Tôi sẽ đi với # 1 hoặC# 3.

Một điều cần xem xét là nếu bạn có một số thứ mà bạn có thể gắn thẻ (ví dụ: thêm thẻ cho cả bài đăng và sản phẩm, ví dụ). Điều này có thể ảnh hưởng đến giải pháp cơ sở dữ liệu.

0

Tôi cũng có cùng một nghi ngờ rằng tôi đã áp dụng giải pháp thứ ba cho trang web của mình. Tôi biết có một cách khác để xử lý vấn đề này với các biến có chiều dài thay đổi bao gồm việc sử dụng các cột như các hàng theo cách này, bạn sẽ có một số thông tin xác định redupant tuple và các thông tin khác nhau được sắp xếp một cho mỗi hàng.

+--------+-------+-------------------------------------+ 
| postId | label | value        | 
+--------+-------+-------------------------------------+ 
| 1 | tag |C++         | 
+--------+-------+-------------------------------------+ 
| 1 | tag |search        | 
+--------+-------+-------------------------------------+ 
| 1 | tag |code         | 
+--------+-------+-------------------------------------+ 
| 1 | title | Why is a raven like a writing desk? | 
+--------+-------+-------------------------------------+ 

Điều này thực sự tồi tệ nhưng đôi khi đó là giải pháp khả thi duy nhất và rất xa cách tiếp cận quan hệ.

+0

nhưng dễ cập nhật và duy trì, truy vấn bị chậm lại nhưng bạn có thể gặp vấn đề về thời gian khi tham gia một số lượng lớn các bộ từ 3 bảng khác nhau, bạn có thể cân nhắc sử dụng các chỉ mục khác nhau để tăng hiệu suất của một số loại truy vấn nhất định. hy vọng điều này đã giúp – urobo

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