2009-02-25 3 views
7

Tôi tò mò muốn biết cách tốt nhất (thực hành tốt nhất) để xử lý cấu trúc phân cấp liên quan đến thiết kế cơ sở dữ liệu là gì. Đây là một ví dụ nhỏ về cách tôi thường xử lý chúng.Xử lý dữ liệu phân cấp trong cơ sở dữ liệu

Node Bảng

NodeId int PRIMARY KEY 
NodeParentId int NULL 
DisplaySeq int NOT NULL 
Title nvarchar(255) 

Tổ Bảng

NodeId int 
AncestorId int 
Hops int 

với chỉ số trên nodeID, AncestorId, Hops

Bàn giống như thế này:

Node Bảng

NodeId NodeParentId DisplaySeq Title 
1   NULL   1    'Root' 
2   1    1    'Child 1' 
3   1    2    'Child 2' 
4   2    1    'Grandchild 1' 
5   2    2    'Grandchild 2' 

Tổ Bảng

NodeId AncestorId Hops 
1   NULL   0 
1   1    0 
2   1    1 
2   2    0 
3   1    1 
3   3    0 
4   1    2 
4   2    1 
4   4    0 
5   1    2 
5   2    1 
5   5    0 

Với thiết kế này, tôi đã tìm thấy rằng với hệ thống phân cấp lớn tôi có thể nhận được toàn bộ một phần của hệ thống phân cấp rất nhanh chóng bằng cách tham gia vào Bảng tổ tiên cho AncestorId = target NodeId, như:

SELECT * 
FROM Node n 
INNER JOIN Ancestor a on a.NodeId=n.NodeId 
WHERE a.AncestorId = @TargetNodeId 

Nó cũng là e muốn nhận con trực tiếp cũng như

SELECT * 
FROM Node n 
INNER JOIN Ancestor a on a.NodeId=n.NodeId 
WHERE a.AncestorId = @TargetNodeId 
AND Hops = 1 

Tôi muốn biết bạn có thể sử dụng giải pháp nào khác cho loại điều này. Theo kinh nghiệm của tôi, hệ thống phân cấp có thể nhận được khá nhiều lông, và bất kỳ cách nào để tối ưu hóa quá trình truy xuất của chúng là rất quan trọng.

Trả lời

4

Như MarkusQ và n8wrl đã chỉ ra, Joe Celko có một số nội dung tốt về vấn đề này.Tôi sẽ chỉ thêm rằng có nhiều cách để mô hình hóa một hệ thống phân cấp (cuốn sách của Joe chứa một số tôi tin rằng, không chỉ là một trong đó ông coi là "tốt nhất"). Quyết định cuối cùng của bạn hy vọng sẽ đưa vào tài khoản nhu cầu cụ thể của riêng bạn. Một số cách khác nhau để mô hình hóa nó là tốt hơn cho các hoạt động viết chuyên sâu trong khi những cách khác là tốt hơn để đọc thường xuyên hoặc nhanh chóng lên và xuống phân cấp. Chỉ cần ghi nhớ những gì hệ thống của bạn sẽ làm với nó.

10

Có một số phần mở rộng nhà cung cấp cụ để làm điều này, nhưng yêu thích cách db-trung tính của tôi xuất phát từ Joe Celko - google 'Joe Celko Trees và các tầng nấc' hoặc mua cuốn sách này: link text

Đây là một rất thông minh thiết lập dựa trên con đường để đi. Dễ phân cấp truy vấn. Tôi đã thêm trường 'parentID' mà bạn có chỉ vì tôi hỏi các câu hỏi 'trực tiếp cho trẻ em' và 'cha mẹ' rất nhiều và làm tăng tốc độ những câu hỏi đó. Nhưng đây là một cách tuyệt vời để có được một truy vấn 'tổ tiên' hoặc 'descdent'.

6

Bạn cũng có thể muốn kiểm tra "bộ lồng" mẫu:

http://www.intelligententerprise.com/001020/celko.jhtml (Liên kết Hỏng)

Hoặc bạn có thể Google để biết thêm.

P.S .: Curses, n8wrl, bạn nhập nhanh hơn tôi!

+0

Sets lồng nhau! Đó là thuật ngữ tôi đang tìm kiếm! – n8wrl

+0

Bài viết khá thú vị. Một vấn đề tôi luôn gặp phải là khi thêm/xóa một nút, bạn phải cập nhật vị trí của mỗi nút khác sau nó. –

+0

Bạn làm. Và đó là câu trả lời của Tom H rất quan trọng. Đối với tôi, điều này làm việc tuyệt vời trên hệ thống phân cấp mà tôi có thay đổi khá thường xuyên. – n8wrl

1

Trong Oracle, bạn có thể sử dụng CONNECT BY/START WITH để truy vấn dữ liệu phân cấp. Trong SQL Server, bạn có thể sử dụng một thủ tục lưu sẵn, mà tự gọi nó đệ quy.

+0

Tôi đã sử dụng các cuộc gọi đệ quy nhưng truy vấn chạy rất chậm, đó là lý do tại sao tôi triển khai bảng tổ tiên, vì vậy tôi có thể thoát khỏi một cuộc gọi đệ quy. –