Birçok ilişki için bir çok modeli nasıl?

4 Cevap php

Veritabanları ve onlarla hiçbir örgün eğitim ile daha önceki deneyimlerinden sadece biraz, ben bu modeli (ve ben PHP ondan gerektiren veri almak) için nasıl biraz şaşırıp. Bu benim modele çalışıyorum budur:

Sitemde her madde için, o Ancak etiketleri yeniden böyle dosya yükleme, php, özyinelemeli vb gibi çoklu etiketler için izin verilir, ben iki farklı öğeleri olabilir ve onlar her php etiketi olabilir.

Bunu nasıl okumak için çalışıyorum ve bunun ya da ben bilmiyorum başka bir şey ile deneyim eksikliği, ama olsun ben kavramını kavramak için görünmüyor olabilir. Görünüşe birlikte ikisini bağlayan bir orta tablo gerekir?

Also once I have this relationship and the tables defined, how would I do things such as: - Retrieve all items with a certain tag? - Retrieve all tags that one item has?

Herkes kavramı benim anlayış güçlendirmek için bu konuda daha fazla okuma liste olabilir eğer yardım için teşekkürler, aynı zamanda büyük olacağını söyledi.

4 Cevap

Db bölüm kolaydır. Bu, herhangi bir SQL motoru sorguları, db nasıl göründüğünü değil görebilirsiniz sadece bir örnek.

CREATE TABLE posts (
    id INT PRIMARY KEY,
    subject VARCHAR(100),
    body TEXT
)

CREATE TABLE tags (
    id INT PRIMARY KEY,
    name VARCHAR(50)
)

CREATE TABLE post_tags (
    post_id INT,
    tag_id INT,
    FOREIGN KEY (post_id) REFERENCES posts (id),
    FOREIGN KEY (tag_id) REFERENCES posts (id)
)

yourTag etiketlemek ile ürün almak için, sadece bu gibi sorgu çalışacak

SELECT P.*
FROM posts P 
    LEFT JOIN post_tags PT ON (PT.post_id = P.id)
    LEFT JOIN tags T ON (T.id = PT.tag_id)
WHERE T.name = 'yourTag';

Kimlikli yazı ile ilişkili etiketleri almak için 123 Bu sorguyu çalıştırın:

SELECT T.*
FROM tags T 
    LEFT JOIN post_tags PT ON (T.id = PT.tag_id)
    LEFT JOIN posts P ON (PT.post_id = P.id)
WHERE P.id = 123;

PHP bölümü için bir çerçeve kullanabilirsiniz. Çoğu (hepsi değilse de) çerçeveler kolayca böyle ilişkileri modeli olabilir. Örneğin CakePHP'de bu böyle yapılır:

class Post extends AppModel {
    $useTable = 'posts';
    $hasAndBelongsToMany = array(
        'Tag' => array(
            'className' => 'Tag'
            'joinTable' => 'post_tags'
            'foreignKey' => 'post_id'
            'associationForeignKey' => 'tag_id'
        )
    );
}

class Tag extends AppModel {
    $useTable = 'tags';
    $hasAndBelongsToMany = array(
        'Post' => array(
            'className' => 'Post'
            'joinTable' => 'post_tags'
            'foreignKey' => 'tag_id'
            'associationForeignKey' => 'post_id'
        )
    );
}

Siz iki tarafını ilişkilendirmek, bir ara tablo kullanmanız gerekir:

--------     1:n    ------------          --------- 
| ITEM |-¦---------<| ITEM_TAG |   n:1    |  TAG  |
| Id   |            | ItemId   |>-------¦-| Id    |
| Name |            | TagId    |          | Name  |
¯¯¯¯¯¯¯¯            ¯¯¯¯¯¯¯¯¯¯¯¯          ¯¯¯¯¯¯¯¯¯

Sonra veri sorgulama için yapmanız gerekenler join, bir select deyimi içinde tablolar:

Etiketi tüm öğeleri "FooTag"

SELECT item.* FROM item 
              JOIN item_tag on item.id = item_tag.itemId
              JOIN tag on item_tag.tagId = tag.id
WHERE tag.Name = 'FooTag'

Adıyla öğe için tüm etiketleri "FooItem"

SELECT tag.* FROM tag 
             JOIN item_tag on tag.id = item_tag.tagId
             JOIN item on item_tag.itemId = item.id
WHERE item.Name = 'FooItem'

Haklısınız, çok-çok ilişkiler örneğin, ek tablo kullanılarak uygulanır konum:

Blog_entry(entry_id, entry_body)
Tag(tag_id, tag_name)
Entry_tag(entry_id, tag_id)

Herhangi bir operasyon birden fazla katılır kullanılarak yapılmaktadır. Benim örnek tabloları kullanarak, tag 'foo' ile tüm girişleri seçmek istiyorsanız Örneğin, size yürütmek zorunda:

select * 
from
    blog_entry, tag, entry_tag
where
    tag.tag_name = 'foo' and
    entry_tag.tag_id = tag.tag_id and
    entry_tag.entry_id = blog_entry.entry_id

Belirli bir giriş (burada kimliği 123 ile) sahip olduğu tüm etiketleri almak için (update):

select tag_name
from
    blog_entry, tag, entry_tag
where
    Blog_entry.entry_id = 123
    entry_tag.tag_id = tag.tag_id and
    entry_tag.entry_id = blog_entry.entry_id

Evet, çok-çok ilişkisi dernek tablo denir, ek, üçüncü bir tablo gerekiyor.

Veritabanı bölümü tüm bu sol katılır ve oldukça dağınık alabilirsiniz ile kodu kullanmak zor, o kadar da zor değil :)

Benim tavsiyem sizin için hatta bazı karmaşık sorguları işlemek Doktrini veya uskur gibi ORM çerçeve, (ben Doktrini tercih rağmen), kullanmaktır.