Autor Zpráva
Petr Stjskal
Profil *
Ahoj,

snažim se vytvořit odkazy mezi dvěma tabulkama knihy a články. v tabulce články je cizí klíč id_knihy a v knihy je klasicky primary key.

CREATE TABLE `articles` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(50) NOT NULL,
  `perex` text NOT NULL,
  `text` text NOT NULL,
  `autor` varchar(25) NOT NULL,
  `id_knihy` int(11) NOT NULL DEFAULT '0',
  `datum` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id_knihy` (`id_knihy`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE `books` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(25) NOT NULL,
  `caption` text NOT NULL,
  `date` datetime NOT NULL,
  `autor` varchar(25) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`),
  CONSTRAINT `books_ibfk_1` FOREIGN KEY (`id`) REFERENCES `articles` (`id_knihy`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

tabulky teď vypadají takto.

Tabulka article obsahuje několik článků. Tabulka books je zatím prázdná. Podařilo se mi na ní vytvořit cizí klíč s odkazem na article.id_knihy. V tabulce books teď ale nejde přidat žádná položka.

Hlasí to:
"
Cannot add or update a child row: a foreign key constraint fails (`test`.`books`, CONSTRAINT `books_ibfk_1` FOREIGN KEY (`id`) REFERENCES `articles` (`id_knihy`)
"

Myslím, že by to mělo být naopak, odkazovat z id knihy na primarní klíč u knih. Tam ale nejde klíč vytvořit vůbec hlasí mi to:

"
Zdrojové a cílové sloupce musí mít stejný datový typ, nad cílovými sloupci musí být definován index a odkazovaná data musí existovat.
Cannot add or update a child row: a foreign key constraint fails (`test`.`#sql-498_42`, CONSTRAINT `#sql-498_42_ibfk_1` FOREIGN KEY (`id_knihy`) REFERENCES `books` (`id`)).

co s tím má dělat, nebo jak to nastavit správně? Dělám to prvně, díky.
"
Zechy
Profil
Myslim, ze hlaska, ze sloupce musi mit stejny datovy typ a definovany index mluvi jasne
Petr Stjskal
Profil *
`id_knihy` int(11) NOT NULL DEFAULT '0'


KEY `id_knihy` (`id_knihy`)

id` int(11) NOT NULL AUTO_INCREMENT,

ale všechno co to má mít to má. nebo ne?
juriad
Profil
Články jsou v knize, takže to má být:

CREATE TABLE books (
  id INT PRIMARY KEY AUTO_INCREMENT
);

CREATE TABLE articles (
  id INT PRIMARY KEY AUTO_INCREMENT,
  book_id INT NOT NULL REFERENCES books (id)
  # nebo alternativně:
  # CONSTRAINT article_in_book FOREIGN KEY (book_id) REFERENCES articles (id);
);

Několik poznámek:
1) ty zpětné apostrofy ` skoro nikdy nejsou třeba
2) dodržuj jeden jazyk autor x author, datum x date, id_knihy x book_id
3) cizí klíč je vždy definovaný v tabulce, ve které je sloupec, kterým se odkazuješ
4) ten default 0 u cizího klíče je blbost
5) 25 nebo 50 znaků na titulek je dost málo
6) autor by měl spíš být odkaz do tabulky uživatelů/autorů, tedy číslo
7) nazvat sloupec jen date je takové divné; lepší je v tomto případě něco jako published, added, created.
_es
Profil
juriad:
ty zpětné apostrofy ` skoro nikdy nejsou třeba
Ale je asi lepšie ich uvádzať vždy, než neskôr rozmýšľať nad ťažko odhaliteľnou chybou. Okrem toho, pri zložitejších dotazoch to môže zreteľnejšie oddeľovať názvy od kľúčových slov SQL - je to vidno aj na tunajšom „ofarbení kódu“.
juriad
Profil
_es:
Osobně je nepoužívám v ručně psaném SQL nikdy; v případě, že by nastal konflikt s klíčovým slovem, tak raději změním definici tabulky/sloupce v databázi a toto vyžaduji po všech, se kterými spolupracuji.
Zpětné apostrofy podle mě mají smysl jen u blbě navržených databází a při automatickém generování dotazů, které mohou pocházet od BFU.
_es
Profil
juriad [#6]:
Nikdy však nemáš istotu, že trebárs nenastane konflikt až v nejakej budúcej verzii databázového servera. Nevidím dôvod, prečo by nemohli byť názvy tabuliek či stĺpcov ľubovoľné, keď je to možné.

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: