2009-05-29 66 views
7

Tôi đang tạo trang web video nơi các danh mục sẽ được lồng vào nhau:Làm cách nào để tạo danh mục lồng nhau trong Cơ sở dữ liệu?

ví dụ: Ngôn ngữ lập trình-> C -> Video MIT -> Video 1 Lập trình -> Ngôn ngữ C -> Stanford Video -> Video 1 Lập trình -> Python -> Video 1

Danh mục và danh mục phụ này sẽ được tạo người dùng đang bay. Tôi sẽ cần hiển thị chúng khi mọi người tạo chúng dưới dạng menu điều hướng để mọi người có thể duyệt bộ sưu tập dễ dàng.

Ai đó có thể giúp tôi với cách tôi có thể tạo một cơ sở dữ liệu như vậy không?

+0

trùng lặp? http://stackoverflow.com/questions/317322/optimized-sql-for-tree-structures –

+0

https://stackoverflow.com/questions/17081951/my-sql-multiple-category-subcategory-subcategory – Calvin

Trả lời

7

Quassnoi nói:

Bạn nên sử dụng một trong hai bộ lồng nhau hoặc mô hình cha-con.

Tôi đã từng triển khai cả hai. Những gì tôi có thể nói là:

Sử dụng kiến ​​trúc bộ lồng nhau nếu bảng danh mục của bạn không thay đổi thường xuyên, bởi vì trên mệnh đề chọn nhanh và chỉ có một yêu cầu bạn có thể nhận được toàn bộ nhánh của hệ thống phân cấp cho một mục nhất định . Nhưng trên mệnh đề chèn hoặc cập nhật, phải mất nhiều thời gian hơn mô hình con cha mẹ để cập nhật các trường bên trái và phải (hoặc thấp hơn và phía trên trong ví dụ bên dưới).

Một điểm khác, khá tầm thường tôi phải thừa nhận, nhưng:
Rất khó để thay đổi thứ bậc bằng tay trực tiếp trong cơ sở dữ liệu (Có thể xảy ra trong quá trình phát triển). Vì vậy, hãy chắc chắn để thực hiện đầu tiên một giao diện để chơi với các bộ lồng nhau (thay đổi nút cha, di chuyển một nút chi nhánh, xóa một nút hoặc toàn bộ chi nhánh, vv)

Dưới đây là hai bài viết về đề tài này:

điều cuối cùng, tôi đã không thử nó, nhưng tôi đọc ở đâu đó rằng bạn có thể hav e nhiều hơn một cây trong một bảng tập hợp lồng nhau, tôi có nghĩa là một số rễ.

3

Bạn nên sử dụng các mẫu nested sets hoặc parent-child.

Parent-child:

 
typeid parent name 

1  0  Buyers 
2  0  Sellers 
3  0  Referee 
4  1  Electrical 
5  1  Mechanic 
SELECT * 
FROM mytable 
WHERE group IN 
     (
     SELECT typeid 
     FROM group_types 
     START WITH 
       typeid = 1 
     CONNECT BY 
       parent = PRIOR typeid 
     ) 

sẽ chọn tất cả người mua ở Oracle.

Nested sets:

 
typeid lower upper Name 
1  1  2  Buyers 
2  3  3  Sellers 
3  4  4  Referee 
4  1  1  Electrical 
5  2  2  Mechanic 
SELECT * 
FROM group_types 
JOIN mytable 
ON  group BETWEEN lower AND upper 
WHERE typeid = 1 

sẽ chọn tất cả người mua ở bất kỳ cơ sở dữ liệu.

Xem this answer để biết thêm chi tiết.

Nested sets dễ truy vấn hơn, nhưng khó cập nhật và khó xây dựng cấu trúc cây hơn.

11

Thực hiện một bảng thư mục với các lĩnh vực sau:

  • CategoryID - Integer
  • CategoryName - Chuỗi/Varchar/Dù
  • ParentID - Integer

ParentID của bạn sau đó sẽ tham khảo lại vào CategoryID của cha mẹ của nó.

Ví dụ:

CategoryID CategoryName ParentID 
--------------------------------- 
1   Dog   NULL 
2   Cat   NULL 
3   Poodle  1 
4   Dachsund  1 
5   Persian  2 
6   Toy Poodle 3 
+0

Làm cách nào để tôi xây dựng truy vấn để tạo điều hướng từ bảng như vậy? Có đường nào dễ đi không? – MathOldTimer

+0

Jake: Tôi không biết làm thế nào bạn sẽ làm điều hướng của riêng bạn, nhưng cách tiêu chuẩn sẽ được hiển thị một mức duy nhất (chẳng hạn như cấp cao nhất) đầu tiên bằng cách sử dụng một truy vấn như "select * from tblCategories nơi ParentID là NULL" bạn sẽ nhận được Chó và Mèo. Sau đó, khi bạn nhấp vào con chó, bạn có thể có được cấp độ tiếp theo bằng cách truy vấn "Chọn * từ tblCategories nơi ParentID = 1" vì 1 là categoryid của Dog. Và sau đó bạn tiếp tục theo cùng cách thức mà bạn tiếp tục khoan. – TheTXI

+0

Xin cảm ơn! Điều này rất hữu ích! – MathOldTimer

0

gì bạn cần là một mối quan hệ cha-con cơ bản:

Category (ID: int, ParentID: nullable int, Name: nvarchar(1000)) 
5

Từ ví dụ trong câu hỏi của bạn có vẻ như bạn muốn nó trở thành có thể cho một cho thể loại có nhiều cha mẹ (ví dụ: "Video MIT -> Lập trình Video 1" cũng như "Video -> Lập trình Video 1"), trong trường hợp đó chỉ cần thêm cột ParentID sẽ không đủ.

Tôi khuyên bạn nên tạo hai bảng: một bảng Danh mục đơn giản với các cột CategoryID và CategoryName và một bảng CategoryRelationships riêng với cột ParentCategoryID và ChildCategoryID. Bằng cách này bạn có thể chỉ định bao nhiêu mối quan hệ cha-con như bạn muốn cho bất kỳ thể loại cụ thể nào. Nó thậm chí sẽ có thể sử dụng mô hình này để có một mối quan hệ kép, nơi hai loại là cha mẹ và con của nhau cùng một lúc.(. Off đỉnh đầu của tôi, tôi không thể nghĩ ra sử dụng tuyệt vời cho kịch bản này, nhưng ít nhất nó minh họa cách linh hoạt các mô hình là)

+0

Cảm ơn! Đây chính xác là những gì tôi muốn. Như một ví dụ tôi muốn rằng một "video mồi ngôn ngữ lắp ráp" nên được liệt kê trong cả hai "cơ bản kỹ thuật đảo ngược" cũng như "ngôn ngữ lập trình". – MathOldTimer

0

Một cách tốt hơn để lưu trữ các PARENT_ID của bảng là để có nó lồng trong ID ví dụ

100000 Lập trình 110000 C Ngôn ngữ 111.000 Video 1 Lập trình 111.100 C Ngôn ngữ 111.110 Stanford video

v..v..và tất cả những gì bạn cần là một tập lệnh để xử lý ID sao cho chữ số đầu tiên đại diện cho danh mục cấp cao nhất và cứ như vậy khi bạn đi sâu hơn xuống cấu trúc phân cấp

+0

Đây là một cách khá thú vị. Bạn có bất kỳ ý tưởng làm thế nào để truy vấn dữ liệu như vậy mặc dù? –

+0

Điều này không giới hạn bạn đến 10 mục cấp cao nhất 0-9?Lý do để sử dụng các số không là gì, bạn có đang sử dụng một số các số nguyên có giới hạn số lượng con có thể không? Bạn sẽ chèn các mục mới và cập nhật chúng như thế nào? –

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