关于mysql建立外键的问题

zhp_king 2017-05-08 02:03:44
有一个主表字段u_id(主键),u_name等字段,关联表字段id(主键),u_id,u_name(u_id和u_name的数据是对应主表的)那么能不能建一个外键foreign key(u_id,u_name)同时限制这两个字段?

比如说我主表的u_id和u_name改变了,或者是u_id和u_name其中一个改变了,那么从表能否这两个字段(u_id,u_name)也跟着一起变?
...全文
333 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhp_king 2017-05-11
  • 打赏
  • 举报
回复
引用 11 楼 zjcxc 的回复:
操作不当吧? 测试了没问题
drop table if exists c, b, a;
create table a(u_id int primary key);
create table b(id int primary key, u_id int, foreign key(u_id) references a(u_id) on update cascade);
create table c(id int primary key, u_id int, foreign key(u_id) references a(u_id) on update cascade);
insert a values(1);
insert b values(1,1);
insert c values(1,1);
select * from a, b, c;
+------+----+------+----+------+
| u_id | id | u_id | id | u_id |
+------+----+------+----+------+
| 1 | 1 | 1 | 1 | 1 |
+------+----+------+----+------+
1 row in set (0.00 sec)

update a set u_id=11;
select * from a, b, c;
+------+----+------+----+------+
| u_id | id | u_id | id | u_id |
+------+----+------+----+------+
| 11 | 1 | 11 | 1 | 11 |
+------+----+------+----+------+
1 row in set (0.00 sec)




cmd登录mysql,测试出来的结果也是一样,应该不是navicat的问题,是不是mysq的问题?
zhp_king 2017-05-11
  • 打赏
  • 举报
回复
引用 11 楼 zjcxc 的回复:
操作不当吧? 测试了没问题
drop table if exists c, b, a;
create table a(u_id int primary key);
create table b(id int primary key, u_id int, foreign key(u_id) references a(u_id) on update cascade);
create table c(id int primary key, u_id int, foreign key(u_id) references a(u_id) on update cascade);
insert a values(1);
insert b values(1,1);
insert c values(1,1);
select * from a, b, c;
+------+----+------+----+------+
| u_id | id | u_id | id | u_id |
+------+----+------+----+------+
| 1 | 1 | 1 | 1 | 1 |
+------+----+------+----+------+
1 row in set (0.00 sec)

update a set u_id=11;
select * from a, b, c;
+------+----+------+----+------+
| u_id | id | u_id | id | u_id |
+------+----+------+----+------+
| 11 | 1 | 11 | 1 | 11 |
+------+----+------+----+------+
1 row in set (0.00 sec)






更新的时候发现建立了外键的字段没有同时更新,然后查看表结构发现外键没有建立





数据库是mysql,测试用的是navicat,是不是mysql是不支持一个主表对应多个从表建立的外键关系?
zhp_king 2017-05-11
  • 打赏
  • 举报
回复
引用 16 楼 ACMAIN_CHM 的回复:
show create table a; 检查你的默认表存储引擎,myisam不支持外键。
之前的测试也是用了myisam,现在改成innodb可以了,十分感谢!
ACMAIN_CHM 2017-05-11
  • 打赏
  • 举报
回复
show create table a; 检查你的默认表存储引擎,myisam不支持外键。
ACMAIN_CHM 2017-05-10
  • 打赏
  • 举报
回复
引用 10 楼 zhp_king 的回复:
[quote=引用 8 楼 zjcxc 的回复:] 请表的键值唯一是外键的必要条件 如果不唯一,那么主表的某条记录修改,子表怎么对应确定应该改哪些? 如果你没办法满足定义外键的要求,则考虑触发器
还有一个问题请教一下,我有一个主表A和两个从表B,C,建立主表u_id关联的时候,发现和B表的u_id建立了外键之后,A表跟C表就不能建立外键关系了(建立的时候没报错,但只是C表生成了一个u_id的索引),请问是不是一个主表只能和一个从表建立外键关系,而不能和多个从表建立外键关系?[/quote]
mysql> create table c (
    ->  u_id    varchar(10)  ,
    ->  u_name  varchar(20)  ,
    ->  FOREIGN KEY (u_id) references a(u_id) on update cascade,
    ->  FOREIGN KEY (u_name) references a(u_name) on update cascade
    -> );
Query OK, 0 rows affected (0.11 sec)

mysql>
ACMAIN_CHM 2017-05-10
  • 打赏
  • 举报
回复
mysql> create table a (
    ->  u_id    varchar(10) primary key,
    ->  u_name  varchar(20) unique key
    -> );
Query OK, 0 rows affected (0.07 sec)

mysql> insert into a values ('zhk','zhp_king1');
Query OK, 1 row affected (0.01 sec)

mysql> insert into a values ('king','zhp_king2');
Query OK, 1 row affected (0.00 sec)

mysql>
mysql> create table b (
    ->  u_id    varchar(10)  ,
    ->  u_name  varchar(20)  ,
    ->  FOREIGN KEY (u_id) references a(u_id) on update cascade,
    ->  FOREIGN KEY (u_name) references a(u_name) on update cascade
    -> );
Query OK, 0 rows affected (0.06 sec)

mysql> insert into b values ('zhk','zhp_king1');
Query OK, 1 row affected (0.00 sec)

mysql> insert into b values ('king','zhp_king2');
Query OK, 1 row affected (0.01 sec)

mysql> select * from a;
+------+-----------+
| u_id | u_name    |
+------+-----------+
| zhk  | zhp_king1 |
| king | zhp_king2 |
+------+-----------+
2 rows in set (0.00 sec)

mysql> select * from b;
+------+-----------+
| u_id | u_name    |
+------+-----------+
| zhk  | zhp_king1 |
| king | zhp_king2 |
+------+-----------+
2 rows in set (0.00 sec)

mysql>

mysql> update a set u_id='zhk_1' where  u_id='zhk';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from b;
+-------+-----------+
| u_id  | u_name    |
+-------+-----------+
| zhk_1 | zhp_king1 |
| king  | zhp_king2 |
+-------+-----------+
2 rows in set (0.00 sec)

mysql> update a set u_name='zhp_king22' where  u_id='king';
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from b;
+-------+------------+
| u_id  | u_name     |
+-------+------------+
| zhk_1 | zhp_king1  |
| king  | zhp_king22 |
+-------+------------+
2 rows in set (0.00 sec)

mysql> update a set u_id='king222', u_name='zhp_king222' where  u_id='king';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from b;
+---------+-------------+
| u_id    | u_name      |
+---------+-------------+
| zhk_1   | zhp_king1   |
| king222 | zhp_king222 |
+---------+-------------+
2 rows in set (0.00 sec)

mysql>
zjcxc 2017-05-10
  • 打赏
  • 举报
回复
操作不当吧? 测试了没问题
drop table if exists c, b, a;
create table a(u_id int primary key);
create table b(id int primary key, u_id int, foreign key(u_id) references a(u_id) on update cascade);
create table c(id int primary key, u_id int, foreign key(u_id) references a(u_id) on update cascade);
insert a values(1);
insert b values(1,1);
insert c values(1,1);
select * from a, b, c;
+------+----+------+----+------+
| u_id | id | u_id | id | u_id |
+------+----+------+----+------+
|    1 |  1 |    1 |  1 |    1 |
+------+----+------+----+------+
1 row in set (0.00 sec)

update a set u_id=11;
select * from a, b, c;
+------+----+------+----+------+
| u_id | id | u_id | id | u_id |
+------+----+------+----+------+
|   11 |  1 |   11 |  1 |   11 |
+------+----+------+----+------+
1 row in set (0.00 sec)
zjcxc 2017-05-09
  • 打赏
  • 举报
回复
请表的键值唯一是外键的必要条件 如果不唯一,那么主表的某条记录修改,子表怎么对应确定应该改哪些? 如果你没办法满足定义外键的要求,则考虑触发器
zhp_king 2017-05-09
  • 打赏
  • 举报
回复
引用 8 楼 zjcxc 的回复:
请表的键值唯一是外键的必要条件 如果不唯一,那么主表的某条记录修改,子表怎么对应确定应该改哪些? 如果你没办法满足定义外键的要求,则考虑触发器
还有一个问题请教一下,我有一个主表A和两个从表B,C,建立主表u_id关联的时候,发现和B表的u_id建立了外键之后,A表跟C表就不能建立外键关系了(建立的时候没报错,但只是C表生成了一个u_id的索引),请问是不是一个主表只能和一个从表建立外键关系,而不能和多个从表建立外键关系?
  • 打赏
  • 举报
回复
引用 7 楼 zhp_king 的回复:
[quote=引用 2 楼 yupeigu 的回复:] 一般不能实现这样的功能。 如果你有这个要求,建议去外键引用,在触发器中,先更新主表,在更新从表的数据,通过程序来维护主外键的关系
请问如果这种情况不用主键限制的话,那么是在程序中(php)维护主外键的关系还是是用触发器比较好?[/quote] 那肯定是程序中维护比较好,程序更加灵活
zhp_king 2017-05-08
  • 打赏
  • 举报
回复
引用 2 楼 yupeigu 的回复:
一般不能实现这样的功能。 如果你有这个要求,建议去外键引用,在触发器中,先更新主表,在更新从表的数据,通过程序来维护主外键的关系
请问如果这种情况不用主键限制的话,那么是在程序中(php)维护主外键的关系还是是用触发器比较好?
zhp_king 2017-05-08
  • 打赏
  • 举报
回复
引用 4 楼 zjcxc 的回复:
use tempdb;
drop table if exists m, c;

create table m(
	u_id int primary key, u_name varchar(10) unique
);
create table c(
	id int auto_increment primary key,
	u_id int, u_name varchar(10),
	FOREIGN KEY (u_id) references m(u_id) on update cascade,
	FOREIGN KEY (u_name) references m(u_name) on update cascade
);

insert m values(1, 'a'), (2, 'b');
insert c(u_id, u_name) values(1, 'a'), (2, 'b');
select * from m;
select * from c;
update m set u_id=u_id+10;
update m set u_name=concat(u_name, '*');
select * from m;
select * from c;


drop table if exists c, m;
请教一下,如果要建立外键,那么主表外键的字段值一定是要限制是唯一的吗?我看你建立u_name字段外键的时候使用了唯一索引
zjcxc 2017-05-08
  • 打赏
  • 举报
回复
郁闷,FOREIGEN 不能直接在弄上定义,这个和 SQL Server 不一样(但也不报错,也不给警告)
zjcxc 2017-05-08
  • 打赏
  • 举报
回复
use tempdb;
drop table if exists m, c;

create table m(
	u_id int primary key, u_name varchar(10) unique
);
create table c(
	id int auto_increment primary key,
	u_id int, u_name varchar(10),
	FOREIGN KEY (u_id) references m(u_id) on update cascade,
	FOREIGN KEY (u_name) references m(u_name) on update cascade
);

insert m values(1, 'a'), (2, 'b');
insert c(u_id, u_name) values(1, 'a'), (2, 'b');
select * from m;
select * from c;
update m set u_id=u_id+10;
update m set u_name=concat(u_name, '*');
select * from m;
select * from c;


drop table if exists c, m;
zjcxc 2017-05-08
  • 打赏
  • 举报
回复
on update cascade 就可以了,参考下面的示例
use tempdb;
create table m(
	u_id int primary key, u_name varchar(10) unique
);
create table c(
	id int auto_increment primary key,
	u_id int references m(u_id) on update cascade,
	u_name varchar(10) references m(u_namae) on update cascade
);

insert m values(1, 'a'), (2, 'b');
insert c(u_id, u_name) values(1, 'a'), (2, 'b');
select * from m;
select * from c;
update m set u_id=u_id+10;
update m set u_name=concat(u_name, '*');
select * from m;
select * from c;


drop table if exists m, c;
  • 打赏
  • 举报
回复
一般不能实现这样的功能。 如果你有这个要求,建议去外键引用,在触发器中,先更新主表,在更新从表的数据,通过程序来维护主外键的关系
zhujinqiang 2017-05-08
  • 打赏
  • 举报
回复
跟着一起变? 能吗?

56,677

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧