MySQL ebeveyn ->

4 Cevap php

Ben MySQL ile çalışıyorum, ve ben ebeveyn herhangi bir düzeyde bir kimliği ile eşleşen bir tablodan verileri seçmek için gereken bir durum yaşıyorum -> diğer tablodaki çocuk veri hiyerarşisi.

Dahası, ben bu özellik biraz kullanılan olacak gibi değil, benim PHP kodu bir özyinelemeli işlevi daha iyi yazılmış bir SQL sorgusu ile bu sorunu çözmek istiyoruz.

Ben arama denemek yaptım, ve ben ancak bunların hiçbiri bana yardımcı oldu, (çoğu çözümlenen) çok sayıda benzer sorunlar tökezledi.

Durumu göstermek yardımcı olmak için burada benim şimdiki tuzak

table "makaleler":

  • article_id
  • category_id
  • ...

tablo kategorileri

  • category_id
  • parent_id
  • ...

Ben "articles.category_id" olduğu, en, 10 diyelim. Fakat aynı zamanda "categories.category_id" 10 aittir ağacından tüm kategorilerdeki tüm makaleleri almak "makale" den tüm makaleleri seçmek gerekir.

"10" ebeveyn ve çocukların hepsi, ve yukarı 10 çocuk ve anne her nerede nerede, Anlamı.

Özyinelemeli bir php fonksiyonu olmadan mümkün?

Teşekkür ederim.

4 Cevap

Bu MySQL yapmak mümkün, ama biraz çaba gerektirir. Böyle bir işlevi yazmak gerekir:

CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _id INT;
        DECLARE _parent INT;
        DECLARE _next INT;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

        SET _parent = @id;
        SET _id = -1;

        IF @id IS NULL THEN
                RETURN NULL;
        END IF;

        LOOP
                SELECT  MIN(id)
                INTO    @id
                FROM    categories
                WHERE   parent = _parent
                        AND id > _id;
                IF @id IS NOT NULL OR _parent = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @id;
                END IF;
                SET @level := @level - 1;
                SELECT  id, parent
                INTO    _id, _parent
                FROM    categories
                WHERE   id = _parent;
        END LOOP;
END

ve bir sorguda kullanabilirsiniz:

SELECT  id, parent, level
FROM    (
        SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 0,
                        @id := @start_with,
                        @level := 0
                ) vars, categories 
        WHERE   @id IS NOT NULL
        ) ho
JOIN    categories hi
ON      hi.id = ho.id

Daha fazla ayrıntı için bloguma bu girdiyi bakın:

Bu MySQL kullanarak konum göz önüne alındığında, kullandığınız komşuluk listesi tasarım kullanarak bir sorguda bütün bir ağaç almak mümkün değildir.

Veritabanı desteği SQL uzantıları diğer bazı markalar tasarım bu tür işlemek için. Oracle, Microsoft SQL Server, IBM DB2 ve PostgreSQL 8.4 (şu anda beta) desteği SQL uzantıları.

Diğer veritabanı tasarımlar daha verimli ağaçları sorgulamak için izin vardır. Bu soru bloglar, ve makalelerde, StackOverflow birçok kez ele alınmıştır.

Ayrıca derinlemesine birkaç tür tasarımlar gider Joe Celko tarafından "Trees and Hierarchies in SQL for Smarties" okuyabilirsiniz.

Ilişkisel bir veritabanında hiyerarşik veri depolamak için en yaygın desen, komşu liste veya modified preorder (aka nested set) belirtilebilir. Alternatif bir komşu listenin başında oturan, temelde bir önbelleğe alma mekanizması olan bir hayata yolu kullanmaktır. Ayrıca bakınız this table for a comparison of pros and cons.

Ben ne kadar olur bu yardım Seni bilmiyorum, ama ben tek bir MySQL sorgusu kullanarak hiyerarşik bir ağaç oluşturur küçük bir fonksiyon yazdım. Temelde, bütün önemli mantık PHP taşınır. Benim çözüm komşuluk listesi modelini kullanan ve daha sonra düz bir biri ile bir ağaç veri yapısı oluşturmak için PHP referanslar kullanır. Aşağıdaki özü bir göz atın ve size biraz ilham almak olmadığını görmek. Ben size daha fazla yardımcı olur, ama benim iş de uğraşmak zorunda bazı sorunlar var.

http://gist.github.com/104357