InnoDB возвращает странные результаты?

#mysql #innodb #inner-join #foreign-key-relationship

#mysql #innodb #внутреннее объединение #связь с внешним ключом

Вопрос:

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

По какой-то причине я получаю неправильные результаты при тестировании запроса в phpMyAdmin.

У меня есть таблица users, где uid является первичным / уникальным (автоматическое увеличение), и таблица user_profiles, которая имеет uid, который является первичным / уникальным и является внешним ключом к uid пользователей в таблице users, в основном ссылающейся на столбцы uid в обеих таблицах.

Чтобы было проще понять, вот две таблицы:

 CREATE TABLE `users` (
`uid` int(10) unsigned NOT NULL AUTO_INCREMENT,
`status` char(10) NOT NULL DEFAULT 'verify',
`username` varchar(15) NOT NULL,
`email` varchar(50) NOT NULL,
`password` char(32) NOT NULL,
`reg_date` int(11) NOT NULL,
`ip` varchar(39) DEFAULT NULL,
PRIMARY KEY (`uid`),
UNIQUE KEY `username` (`username`),
UNIQUE KEY `email` (`email`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

CREATE TABLE `user_profiles` (
`uid` int(10) unsigned NOT NULL,
`first_name` varchar(40) DEFAULT NULL,
`last_name` varchar(50) DEFAULT NULL,
`gender` char(6) DEFAULT NULL,
`website` varchar(100) DEFAULT NULL,
`msn` varchar(60) DEFAULT NULL,
`aim` varchar(60) DEFAULT NULL,
`yim` varchar(60) DEFAULT NULL,
`twitter` varchar(15) DEFAULT NULL,
PRIMARY KEY (`uid`),
CONSTRAINT `user_profiles_ibfk_1` FOREIGN KEY (`uid`) REFERENCES `users` (`uid`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  

По сути, я добавил несколько фиктивных записей в таблицу users, а затем получил users.uid и добавил uid в user_profiles, чтобы связать фиктивные записи между обеими таблицами.

Теперь проблема, с которой я столкнулся, странная, сначала вот мой запрос, который я использую в phpMyAdmin:

 SELECT * FROM users INNER JOIN user_profiles
ON users.uid = '11'
  

По сути, этот запрос должен выдать мне только одну из фиктивных записей из таблиц users и user_profiles, связав их вместе с помощью uid. Но, как ни странно, это не так. Он возвращает все записи, даже если другие идентификаторы uid отличаются, потому что они уникальны, даже в результате запроса это показывает, что идентификаторы uid уникальны, а не одинаковы, нет дубликатов, которых нет, и база данных в любом случае не разрешила бы это.

Теперь я не понимаю, почему, но он должен возвращать только 1 запись, поскольку uid уникальны, и в users и user_profiles есть только одна запись с uid, равным 11 (которая связывает их с другими по этому uid). Как ни странно, вчера все работало нормально. Итак, я решил удалить тестовую таблицу и начать заново, но то же самое.

У кого-нибудь есть идеи, что происходит?

Ответ №1:

Вы не связываете таблицы на ВКЛ.

Вы ничего не упоминаете из user_profiles , вот почему он принимает их все.

вам нужно поместить в предложение ON условие объединения, а в where — равное.

Запрос должен гласить:

 SELECT * 
FROM   users 
       INNER JOIN user_profiles 
         ON users.uid = user_profiles.uid 
WHERE  users.uid = '11' 
  

Комментарии:

1. о, дорогой, я понимаю, что теперь я по какой-то причине думал О том, было ГДЕ, я не могу в это поверить. Я рвал на себе волосы и думал, что вчера это сработало, лол. Спасибо! 🙂

Ответ №2:

Вы хотите присоединиться к uid users и user_profiles , но это не то, что вы сделали, вы присоединились user_profiles on users.uid = '11' .
Это, конечно, не влияет на user_profiles , потому что вы не установили связь между пользователями и user_profiles.

Изменить:

 SELECT * FROM users INNER JOIN user_profiles
ON users.uid = '11'
  

Для:

 SELECT * FROM users 
INNER JOIN user_profiles ON (users.uid = user_profiles.uid)
WHERE users.uid = '11'
  

Теперь вы указали взаимосвязь между пользователями и их профилями (соответствие uid), и далее вы заявляете, что вам нужны только пользователи с uid 11.

Ответ №3:

В предложении ON вы должны указать поля объединения обеих таблиц, а не условие фильтрации, например SELECT * FROM users INNER JOIN user_profiles ON users.uid = user_profiles.uid . После этого вы можете добавить предложение WHERE как обычно, например WHERE users.uid = '11'