2010-03-25 10 views
9

Tôi đang cố gắng xây dựng hệ thống điều hướng bằng cách sử dụng bảng danh mục có cấu trúc phân cấp. Thông thường, bảng sẽ được xác định như sau:MySQL & PHP - Tạo nhiều mối quan hệ cha mẹ con

id (int) - Primary key 
name (varchar) - Name of the Category 
parentid (int) - Parent ID of this Category referenced to same table (Self Join) 

Nhưng nắm bắt được rằng tôi yêu cầu một thể loại có thể đứa trẻ nhiều loại cha mẹ .. Cũng giống như một Has và Thuộc Nhiều (HABTM) liên quan.

Tôi biết rằng nếu có hai bảng, loại & mục, chúng tôi sử dụng bảng tham gia categories_items để liệt kê các mối quan hệ HABTM. Nhưng ở đây tôi không có hai bảng nhưng chỉ có bảng nhưng bằng cách nào đó nên thể hiện mối quan hệ HABTM với chính nó. Đây có phải là có thể sử dụng một bảng duy nhất? Nếu có, Làm thế nào? Nếu không thể, tôi nên làm theo các quy tắc nào (đặt tên bảng, trường) trong khi tạo bảng nối bổ sung?

Tôi đang cố gắng đạt được điều này bằng CakePHP, Nếu ai đó có thể cung cấp giải pháp CakePHP cho vấn đề này, điều đó thật tuyệt vời. Ngay cả khi điều đó là không thể, bất kỳ giải pháp nào về việc tạo bảng nối được đánh giá cao. Cảm ơn vì đã dành thời gian cho tôi.

- Chỉnh sửa - Câu hỏi của tôi có vẻ hơi khó hiểu, vì vậy tôi đang cố gắng khôi phục lại những gì tôi đang tìm kiếm. Trong mối quan hệ cha-con tự tham chiếu (tự tham gia) truyền thống, mỗi mục chỉ có thể có một phụ huynh. Những gì tôi đang tìm kiếm là mô phỏng mối quan hệ HABTM, nghĩa là nhiều bậc cha mẹ cho mỗi mục.

Danh mục & Mục - Để xác định HABTM, chúng tôi sử dụng bảng category_items.

Nếu trong Danh mục tôi cần HABTM, tôi nên làm gì?

+0

u có thể tiết kiệm giá trị đa trong một lĩnh vực bằng cách tách chúng bằng dấu phẩy hoặc một số seperator –

+0

1 câu hỏi thú vị :-) – richsage

+0

Tôi thấy điều này trong khi googling, http://n2.nabble.com/Saving-self- tham chiếu-HABTM-mối quan hệ-td1126141.html, tôi đã cố gắng để nhân rộng giống nhau, nhưng vẫn Bánh không bắt được sự liên kết. Ý tưởng, ai đó? – Ashok

Trả lời

0

Got nó cuối cùng.

Naviitems Bảng:

CREATE TABLE IF NOT EXISTS `naviitems` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `linkurl` varchar(250) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

Tự Tham Bảng:

CREATE TABLE IF NOT EXISTS `naviitems_parents` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `naviitem_id` int(11) NOT NULL, 
    `parent_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

Naviitems mẫu:

<?php 
class Naviitem extends AppModel { 

    var $name = 'Naviitem'; 

    //The Associations below have been created with all possible keys, those that are not needed can be removed 
    var $hasAndBelongsToMany = array(
     'Parent' => array(
      'className' => 'Naviitem', 
      'joinTable' => 'naviitems_parents', 
      'foreignKey' => 'naviitem_id', 
      'associationForeignKey' => 'parent_id', 
      'unique' => true, 
      'conditions' => '', 
      'fields' => '', 
      'order' => '', 
      'limit' => '', 
      'offset' => '', 
      'finderQuery' => '', 
      'deleteQuery' => '', 
      'insertQuery' => '' 
     ) 
    ); 
} 
?> 

tôi đã tạo điều khiển và xem sử dụng Bánh Nướng vỏ. Nó hoạt động tốt ngay bây giờ. Cảm ơn tất cả những ý tưởng bạn đã đóng góp, họ đã giúp tôi rất nhiều.

0

Những gì bạn đang cố gắng đạt được không thực sự là cách tiếp cận Bánh. Bạn nên sử dụng hai bảng với một bảng nối giữa. Bánh tối đa là 'quy ước về cấu hình' vì vậy bạn nên thực sự sử dụng cách bánh chuẩn.

Để tạo HABTM, bạn sẽ muốn có ba bảng.

items 
categories 
categories_items 

Hạng mục và danh mục như bạn mong muốn. Bảng tham gia của bạn chỉ nên chứa hai id của các bảng đã tham gia như sau,

category_id 
item_id 

Điều này sẽ cho phép bạn có một mục điều hướng xuất hiện trong nhiều danh mục, nếu bạn chọn.

Thông tin thêm có thể được tìm thấy trong cuốn sách, http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

+0

Cảnh báo: Ashok không có hai bảng, nhưng chỉ có một bảng đề cập đến chính nó. :) – pinkgothic

+0

Đây là 'cách bánh' theo yêu cầu trong câu hỏi :) –

+0

Bạn hiểu lầm câu hỏi của tôi ... Tôi không cố tạo HABTM giữa Danh mục và Mục ... Tôi đang cố gắng tạo HABTM trong Bảng danh mục. – Ashok

2

Đang cố gắng để ép một n: mối quan hệ m (HABTM) vào một 1: n mối quan hệ không phải là thực hành tốt và bạn sẽ chạy vào các giới hạn bạn sẽ không nếu bạn đã làm điều đó một cách rõ ràng, nhưng đây là cách bạn có thể làm điều đó (chung PHP, không phải CakePHP cụ thể):

Bạn có thể tạo một cột trong bảng của mình để lưu trữ tất cả ID cha trong danh sách được phân cách bằng dấu phẩy. Bạn có thể đọc các ID cá nhân ra bằng cách sử dụng ...

$ids = explode(',', $idsFromColumn); 

... và viết chúng trở lại vào cột sử dụng ...

$idsForColumn = implode(',', $ids); 

thực tế đọc-ghi của cơ sở dữ liệu sẽ xảy ra trước/sau những đoạn đó, tương ứng.


Nếu bạn muốn làm điều đó đúng cách, bạn muốn bạn bảng chính để xem xét như thế này:

id (int) - Primary key 
name (varchar) - Name of the Category 

Và n: mối quan hệ m bảng trông như thế này:

id (int) - child 
parentid (int) - parent 

Bạn sẽ truy vấn nó như sau:

SELECT ... 
FROM 
    main_table AS m 
    [LEFT OUTER|INNER] JOIN 
    relationship_table AS r 
     ON r.id=m.id 
    [LEFT OUTER|INNER] JOIN 
    main_table AS n 
     ON r.parentid=n.id 
WHERE ... 

Chính xác những gì bạn muốn trong bạn WHERECHỌN của bạn sẽ tùy thuộc vào những gì bạn mong muốn đạt được. Để biết bạn có muốn LEFT OUTER JOIN hoặc INNER JOIN, điều đó phụ thuộc vào việc bạn muốn trả về các danh mục theo m. * Không có mục nhập trong mối quan hệ của bạn (= không có bất kỳ phụ huynh nào). Nếu bạn mới tham gia cú pháp, hãy xem this Wiki article on joins.

+0

Cảm ơn bạn, điều này rất hữu ích. – Ashok

1

Đây gần như chính xác những gì mà Tree behaviour được thiết kế cho. Hành vi được xây dựng trên đầu trang của MPTT (Modified Preorder Tree Traversal). Bạn sẽ cấu hình nó như sau:

Thêm các lĩnh vực sau đây để bàn của bạn:

`parent_id` int(10) unsigned default NULL 
`lft` int(10) unsigned default NULL 
`rght` int(10) unsigned default NULL 

mẫu:

class Category extends AppModel 
{ 
    var $actsAs = array('Tree'); 
} 

Sau đó bạn muốn xây dựng một PARENT_ID <select> thành các dạng chủng loại-sửa đổi của bạn, và Hành vi của cây sẽ chăm sóc phần còn lại. Tôi cho rằng bạn có thể xử lý thủ công việc sắp xếp lại các danh mục trong một cấp phân cấp danh mục của bạn, nhưng bạn có thể sử dụng các phương thức moveUpmoveDown có sẵn trong các mô hình mở rộng với hành vi của Cây.

Ở đây, cũng, là hữu ích Tree Helper để chuyển đổi danh sách cây thành các danh sách được sắp xếp/sắp xếp thứ tự trong chế độ xem của bạn.

+1

Xin chào, nhưng ngay cả hành vi của Cây cũng không xử lý nhiều mối quan hệ HABTM con mẹ. Trong liên kết bạn đã cung cấp, http://book.cakephp.org/view/91/Tree, như bạn có thể thấy rằng mỗi thể loại có thể là một danh mục con chỉ một lần .. Nói cách khác, mỗi thể loại chỉ có thể có một phụ huynh. Những gì tôi đang tìm kiếm là nhiều phụ huynh cho mỗi thể loại ... – Ashok

+0

Oof, tôi đã hiểu sai bạn. Lời xin lỗi của tôi. –

3

Tôi hy vọng nó không phải là hình thức xấu để trả lời lần thứ hai, lần đầu tiên hiểu sai câu hỏi. Về cơ bản, việc triển khai CakePHP là câu trả lời của pinkgothic.

New HABTM tham gia bảng:

CREATE TABLE `categories_parent_categories` (
    `category_id` int(10) unsigned NOT NULL, 
    `parent_category_id` int(10) unsigned default NULL, 
    `order` int(10) unsigned NOT NULL default '0' 
); 

Hiệp hội trong mô hình:

class Category extends AppModel 
{ 
    var $hasAndBelongsToMany = array(
     'ParentCategory' => array(
      'className'    => 'Category', 
      'joinTable'    => 'categories_parent_categories', 
      'foreignKey'   => 'category_id', 
      'associationForeignKey' => 'parent_category_id', 
      'order'     => 'CategoriesParentCategory.order' 
     ) 
    ); 
} 
+0

Xin chào, Cảm ơn bạn đã cố gắng giúp tôi, nhưng tôi sợ mã không hoạt động .. Bánh đã không bắt được liên kết. Khi thêm một mục, nó không hiển thị tùy chọn để chọn một id cha .. – Ashok

+0

Cảm ơn bạn đã nhập Hobonium, tôi đã có thể nhận được giải pháp bằng một số sửa đổi từ mã của bạn. Tôi đã đăng nó xuống đây. – Ashok