Таблицы ключ значение и как их использовать в 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')

Применять такие таблицы нужно в крайней необходимости и очень осторожно. Иногда этот способ хранения данных является наиболее приемлемым, так что дерзайте.
Теги:
ключ значение
Добавлено: 16 Мая 2018 08:48:50 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...