mysql - 如果 FK 表具有复合主键(FK 不是复合的一部分),则外键作为主键不起作用

标签 mysql foreign-keys primary-key foreign-key-relationship composite-primary-key

两个表,使用这些脚本创建:

create table user_auth
(
    username varchar(255) NOT NULL,
    password varchar(255) NOT NULL,
    user_id varchar(36) NOT NULL,
    PRIMARY KEY(username, password)
)engine=innodb;

create table user
(
    user_id varchar(36) NOT NULL,
    PRIMARY KEY(user_id),
    FOREIGN KEY(user_id) REFERENCES user_auth(user_id) ON DELETE CASCADE
)engine=innodb;

我得到错误: 无法创建表 'xxx.user' (errno: 150)

外键错误。

如果我改为这样做(删除外键约束但仍引用 user_auth):

create table user_auth
(
    username varchar(255) NOT NULL,
    password varchar(255) NOT NULL,
    user_id varchar(36) NOT NULL,
    PRIMARY KEY(username, password)
)engine=innodb;

create table user
(
    user_id varchar(36) NOT NULL REFERENCES user_auth(user_id) ON DELETE CASCADE,
    PRIMARY KEY(user_id),
)engine=innodb;

一切都很好,但是我可以将 user_id 插入到用户表中,而 user_auth 中没有相应的键,这在我的引用完整性中造成了漏洞。

现在开玩笑说我这样做(删除组合键并使 user_id 成为 user_auth 中的主键):

create table user_auth
(
    user_id varchar(36) NOT NULL,
    PRIMARY KEY(username, password)
)engine=innodb;

create table user
(
    user_id varchar(36) NOT NULL,
    PRIMARY KEY(user_id),
    FOREIGN KEY(user_id) REFERENCES user_auth(user_id) ON DELETE CASCADE
)engine=innodb;

这也有效,尽管我没有用户名/密码组合来确保唯一性。

我有一种感觉,我遗漏了一些关于 MySQL 工作原理的非常关键的东西。请指教。

感谢您的宝贵时间!

更新

在他们的回答中链接的文章 ypercube 中,第三点提到了 PK 的顺序和相应的 FK 必须相同。如果我按以下顺序将 user_id 作为 PK 添加到 user_auth 中,则脚本有效:

create table user_auth
(
    username varchar(255) NOT NULL,
    password varchar(255) NOT NULL,
    user_id varchar(36) NOT NULL,
    PRIMARY KEY(user_id, username, password)
)engine=innodb;

create table user
(
    user_id varchar(36) NOT NULL,
    PRIMARY KEY(user_id),
    FOREIGN KEY(user_id) REFERENCES user_auth(user_id) ON DELETE CASCADE
)engine=innodb;

所以我仍然可以 SELECT 等等,但是现在我不能创建重复的用户名/密码组合,因此每个帐户都是唯一的,因为在我可以之前必须存在用户名/密码/user_id 记录插入用户数据。

最佳答案

尝试:

create table user_auth
(
    username varchar(255) NOT NULL,
    password varchar(255) NOT NULL,
    user_auth_id varchar(36) NOT NULL,
    PRIMARY KEY(username, password)
)engine=innodb;

create table user
(
    user_id varchar(36) NOT NULL,
    user_username varchar(36) NOT NULL, 
    user_pass varchar(36) NOT NULL, 
    INDEX(user_username, user_pass),
    PRIMARY KEY(user_id),
    FOREIGN KEY(user_username, user_pass) REFERENCES user_auth(username, password) ON DELETE CASCADE
)engine=innodb;

引用:http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

关于mysql - 如果 FK 表具有复合主键(FK 不是复合的一部分),则外键作为主键不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14620369/

相关文章:

Mysql新建表

mysql - 播种时违反完整性

python - 跨模板django传递对象主键

python - 如何用该表唯一的不同整数替换 Django 的主键

mysql - where 子句中的列 'date_start' 不明确

javascript - Nodejs node-mysql模块未连接到数据库

mysql - 无法安装 Mysql for Visual Studio 1.2.7

python - 从选择查询中排除 id 字段

entity-framework-4 - Entity Framework : Map Foreign Key without Navigation Property?

mysql - 在与现有自动增量主键/分区键相关的列中添加唯一约束