Таблицы ключ значение и как их использовать в PHP/MYSQL

Эта статья для продвинутых программистов, но и новички смогут всё понять, если будут внимательны. Применение принципа ключ значение в таблицах бывает полезно тогда, когда нам в одной таблице необходимо хранить информацию о другой таблице. Предположим, что у нас есть таблица пользователей. И всё было бы хорошо, но однажды босс захотел хранить ещё несколько телефонов, пол, дату рождения…

Если вы попытаетесь предугадать все пожелания начальника, то ваша таблица будет постоянно расти в горизонтальном направлении.

Тут-то нам и пригодятся таблицы ключ значение. Создадим таблицу для пользователей:
 	CREATE TABLE IF NOT EXISTS `users` (
 	  `id` int(11) NOT NULL AUTO_INCREMENT,
 	  `username` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 	  `pass` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
 	  PRIMARY KEY (`id`)
 	) ENGINE=MyISAM ;

В ней будут хранится самые примитивные данные. Ну а теперь создадим дополнительную таблицу, в которой будем хранить всё остальное.
 	CREATE TABLE IF NOT EXISTS`user_details` (
 	  `id` int(11) NOT NULL AUTO_INCREMENT,
 	  `user_id` int(11) NOT NULL,
 	  `key` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 	  `value` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
 	  PRIMARY KEY (`id`)
 	) ENGINE=MyISAM;

На самом деле поля key и value будут хранить информацию о пользователе. Поскольку в такой таблице информация будет расти вертикально, то мы можем в любой момент добавить новые атрибуты пользователя.

Довольно лирики. Теперь для того, чтобы вставлять данные в эту таблицу, нам необходимо использовать запросы типа:
 	UPDATE user_data SET value = 'What?' WHERE key = 'date_of_birth'

Таким образом у нас есть ключ, по которому мы будем искать необходимое нам значение. Однако в этом способе есть и свои минусы. Допустим нам надо найти всех пользователей из Чикаго. Имея одну таблицу, мы бы это сделали так:
	SELECT username FROM users WHERE city = 'Chicago'

Всё просто. С таблицами ключ значение будет посложнее:
 	SELECT username FROM users a
 	INNER JOIN user_data b
 	    ON a.id = b.user_id
 	WHERE b.key = 'city'
 	AND b.value = 'Chicago'

Довольно-таки громоздко для такой простой задачи. Но это ещё не самое страшное. Проблемы начинаются там, где нам надо произвести поиск по нескольким критериям. В случае с одной таблицей эта задача решается так:
 	SELECT username FROM users WHERE city = 'Chicago' AND state = 'Illinois'

Если вы используете таблицы ключ значение, то можете попасться в капкан следующего выражения:
 	SELECT username FROM users a
 	    INNER JOIN user_data b
 	    ON a.id = b.user_id
 	WHERE
 	    (b.key = 'city' AND b.value = 'Chicago')
 	AND
 	    (b.key = 'state' AND b.value = 'Illinois')

Но это выражение всегда вернут 0. Это происходит потому, что в базе никогда не будет одной и той же строки, которая содержит 2 значения одновременно.

Но решение есть – похожее на монстра:
 	SELECT username FROM users a
 	INNER JOIN user_data b
 	ON a.id = b.user_id
 	    INNER JOIN user_data c
 	    ON b.user_id = c.user_id
 	WHERE
 	    (b.key = 'city' AND b.value = 'Chicago')
 	AND
 	    (c.key = 'state' AND c.value = 'Illinois')

Применять такие таблицы нужно в крайней необходимости и очень осторожно. Иногда этот способ хранения данных является наиболее приемлемым, так что дерзайте.
Добавлено: 21 Августа 2013 11:31:32 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...