#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'