Autor Zpráva
zacatecnik1
Profil *
Dobrý den,

strukturu tabulek i s ukázkovými daty přikládám níže. Jde o tabulku uživatelů a další tabulku jazyků, kdy uživatel může mít přirazen libovolný počet jazyků.

Do teď jsem data vybíral tak, že jsem si vybral uživatele a v php v iteraci jsem při každém průchodu vytvářel nový select pro výběr jazyků. Při velkém množství uživatelů je to ovšem velmi neefektivní.

Lze napsat pouze jeden SQL dotaz tak, abych byl select efektivní a nenáročný?


Děkuji moc za rady.

T.


CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

INSERT INTO `user` (`id`, `name`) VALUES
(1, 'Tomas');

CREATE TABLE `language` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `name` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  `level` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  CONSTRAINT `language_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `language` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

INSERT INTO `language` (`id`, `user_id`, `name`, `level`) VALUES
(1,    1,    'anglictina',    1),
(2,    1,    'nemcina',    2),
(3,    1,    'rustina',    1);
Icka
Profil *
Něco jako:

Select user.*, lang.*
FROM user
LEFT JOIN language AS lang ON lang.user_id = user.id
Tori
Profil
Z hlediska návrhu by ovšem pro vztah M:N bylo správnější toto:
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

-- tady jenom jazyky
CREATE TABLE `language` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8_czech_ci NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;

-- vazební tabulka uživatelů a jazyků
CREATE TABLE `users_languages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `language_id` int(11) NOT NULL,
  `level` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `user_id` (`user_id`),
  KEY `language_id` (`language_id`),
  CONSTRAINT `user_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `language_ibfk_1` FOREIGN KEY (`language_id`) REFERENCES `language` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci;
Primární klíč z users_languages záleží na aplikaci - osobně bych použila pro primární klíč oba FK, aby se zabránilo duplicitním záznamům. Ale jestli nad tím je nějaké ORM, tak tam možná bude potřeba mít sloupec id a unikátnost zajišťovat na straně aplikace.
zacatecnik1
Profil *
Icka:
to je přesně ono :) děkuji

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: