Как я могу объединить данные из мета-таблицы ключ: значение в MySQL?

0

Скажем, у меня есть три таблицы в моей базе данных:

CREATE TABLE `users` (
`user_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR(16) NOT NULL
);

CREATE TABLE `users_meta` (
`meta_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`key` VARCHAR(200) NOT NULL ,
`value` TEXT NOT NULL
);

CREATE TABLE `posts` (
`post_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`content` TEXT NOT NULL
);

Таблица users_meta - это просто хранилище информации о значении ключа для пользователей, так что мы можем добавить любую желаемую информацию.

Скажем, я добавил пару ключ = > значение в таблицу users_meta для каждого пользователя, где ключ был "age", а значение было числом, представляющим их возраст.

Учитывая этот набор обстоятельств, какой лучший способ выбрать первые 10 сообщений, упорядоченных по возрасту пользователя?

  • 0
    Лучший способ - как можно быстрее покинуть эту структуру. Это худший дизайн базы данных для запросов.
  • 0
    В таком случае, как бы вы решили вопрос о разрешении применения какой-либо части метаданных к пользователю?
Показать ещё 2 комментария
Теги:

3 ответа

1
Лучший ответ

Мне нравится ставить условие соединения в самом соединении, чтобы было ясно, что я хочу ограниченное соединение:

SELECT p.post_id, p.content
FROM users u 
INNER JOIN users_meta um 
    ON (u.user_id = um.user_id) AND um.key = 'age'
INNER JOIN posts p 
    ON (p.user_id = u.user_id)
ORDER BY um.value
limit 10
  • 0
    На мой взгляд, он смешивает операторы соединения и выбора, что делает код менее читабельным.
  • 0
    Я выбрал этот ответ, потому что он упрощает объединение нескольких мета-полей, так как вы можете присоединиться к мета-таблице несколько раз. Это на самом деле не присутствует в моем примере, но я думаю, хороший вариант использования для этого типа структуры случайных метаданных.
1

Если вы заказываете только по возрасту пользователя, вы выберете 10 сообщений одного пользователя (самого младшего).

Я бы предложил денормализовать и хранить возраст в таблице пользователей напрямую.

1

Согласитесь с @KOHb, но если это именно то, что вы хотите, вот запрос:

SELECT TOP 10 p.id, p.content
FROM users u JOIN users_meta um ON (u.user_id = um.user_id) 
             JOIN posts p ON (p.user_id = u.user_id)
WHERE um.key = 'age'
ORDER BY um.value

Ещё вопросы

Сообщество Overcoder
Наверх
Меню