Autor Zpráva
qwertz123
Profil *
Zdravim,
snazim se navrhnout jednoduhe databazove schema (MySQL).
V tabulce "clanky" chci mit clanek a pomoci ciziho klice bude kazdy clanek propojen se svym autorem.

Ted ten problem: kazdy clanek bude mit prirazene tagy. Tagy bych rad mel v samostatne tabulce. Jak mam ale propojit tabulku "clanky" s tabulkou "tagy"?
Kdyz tabulce "clanky" pridam sloupec "id_tagy", tak pomoci ciziho klice muzu pouzit prave jeden tag. Ja jich ale potrebuju vic. Jak se to da resit?
Me napade jenom prasarna jako vytvorit v tabulce "clanky" sloupec "id_tagy" jako varchar a napr. v CVS formatu ukladat id jednotlivych tagu z tabulky "tagy".
Takze bych tam mel: "1,7,2,123489,3" a pak bych to pri zpracovani musel pomoci php explode rozlozit.
Ale pri vyhledavani to bude strasne pomaly. :-(

Jak se to ma spravne resit?
Dekuji za rady!

Tori
Profil
To není 1:N, ale N:N (používá se i "M:N"). Mezi tabulkami tagy a clanky bude vazební tabulka (id_clanku, id_tagu), primární klíč přes oba sloupce. Pokud by článek mohl mít více autorů, použije se tam totéž.
qwertz123
Profil *
Takze bych to mel udelat takhle nejak?



Jak ale dam jednomu clanku treba 10 tagu? To budu muset mit v tabulce clankyTagy 10 zaznamu pro jeden clanek?
Keeehi
Profil
qwertz123:
Ano tak. Toto je správné řešení.
qwertz123
Profil *
Muzete mi to prosim nekdo zkontrolovat?

CREATE TABLE clankyTagy
(
    id_clanky INTEGER NOT NULL,
    id_tagy INTEGER NOT NULL,
    PRIMARY KEY (id_clanky, id_tagy),
    KEY (id_tagy)
);

CREATE TABLE tagy
(
    id INTEGER NOT NULL AUTO_INCREMENT,
    jmeno VARCHAR(20),
    PRIMARY KEY (id)
);

CREATE TABLE autori
(
    id INTEGER NOT NULL AUTO_INCREMENT,
    jmeno VARCHAR(50),
    prijmeni VARCHAR(50),
    prezdivka VARCHAR(50) NOT NULL,
    email VARCHAR(50) NOT NULL,
    heslo VARCHAR(50) NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE clanky
(
    id INTEGER NOT NULL AUTO_INCREMENT,
    datum DATETIME NOT NULL,
    titulek VARCHAR(100) NOT NULL,
    uvod TEXT NOT NULL,
    text TEXT NOT NULL,
    id_autori INTEGER NOT NULL,
    id_clanky INTEGER NOT NULL,
    PRIMARY KEY (id),
    UNIQUE UQ_clanky_id_clanky(id_clanky),
    KEY (id_autori)
);

ALTER TABLE clankyTagy ADD CONSTRAINT FK_clankyTagy_tagy 
    FOREIGN KEY (id_tagy) REFERENCES tagy (id);

ALTER TABLE clanky ADD CONSTRAINT FK_clanky_autori 
    FOREIGN KEY (id_autori) REFERENCES autori (id);

Budu mit data:

INSERT INTO autori (prezdivka, email, heslo)
VALUES ('AhojSvete', 'ahoj@svete.cz', 'nbustr123');

INSERT INTO tagy (jmeno)
VALUES ('pocitace');

INSERT INTO tagy (jmeno)
VALUES ('windows');

INSERT INTO tagy (jmeno)
VALUES ('mac');

A kdyz pak budu vkladat tak pouziju:

INSERT INTO clanky (datum, titulek, uvod, text, id_autori, id_clanky)
VALUES ('2012-07-18 21:28:17', 'Titulek clanku', 'Tady bude uvod clanku', 'a toto uz je text...', 1, ???);

Co mam dat misto otazniku a jak mam propojit tabulku clanky s tabulkou tagy pomoci tabulky clankyTagy aby mel clanek prirazeny 2 tagy: "pocitace, windows"?
Keeehi
Profil
id_clanky - přidej k tomu AUTO_INCREMENT
qwertz123
Profil *
CREATE TABLE clankyTagy
(
    id_clanky INTEGER NOT NULL AUTO_INCREMENT,
    id_tagy INTEGER NOT NULL,
    PRIMARY KEY (id_clanky, id_tagy),
    KEY (id_tagy)
);
Takhle?

Jak ale mam pridat novy clanek? Jak mam realizovat to propojeni s tabulkou clankyTagy ?
Keeehi
Profil
qwertz123:
Ne auto_integer měl být u článků. Vložíte článek, vygeneruje se k tomu unikátní id, to si zjistíte a pak vkládáte do clankyTagy to id, které zjistíte a do druhého sloupce id tagu který chcete přiřadit.
qwertz123
Profil *
Aha, takze tabulka clankyTagy pak bude pro jeden clanek obsahovat vic zaznamu:
clankyTagy (id_clanky INTEGER NOT NULL, id_tagy INTEGER NOT NULL);

pro clanek 1, ktery bude mit 2 tagy (v tabulce tagy s id 10 a 12345) bude v tabulce clankyTagy:
1, 10
1, 12345

Pochopil jsem to uz konecne? :-)
Tori
Profil
Správně. Ještě jsem si všimla - sloupec clanky.id_clanku je tam asi navíc, vazba bude clanky.id = clankyTagy.id_clanku.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: