一对多关系,主外键问题!!!???

时间:2022-12-29 21:01:16
表User
UserID(主键,自增),UserName,GroupID(组ID,一个用户只能在一个组中)

表UserLoginLog(登录日志)

LogID(主键,自增),UserID(普通int),LogTime


表UserGroup(用户所在组)

GroupID(主键,自增),GroupName

一个会员有多个登录日志记录吧

那表User和UserLoginLog难道不是所谓的“一对多”关系?为什么我今天看到有人说,表User和UserGroup是一对多关系,(注:一个人只能在一个组中,但一个组可以有多个成员)这样是一对多,难受,看上去表User和UserGroup是一条记录对应一条记录。

问题一:到底表User和UserLoginLog是一对多关系,还是表User和UserGroup是一对多关系

问题二:我在表User和UserLoginLog建立主外键,sqlserver中没问题,但在ORM中总提示这种做法不合理,甚至报错

主外键我是这样建的,在UserLoginLog中建立外键,表User主键UserID,表UserLoginLog外键UserID,删除归则为层叠,这有错吗,在sqlserver中删除User表中一条记录时,UserLoginLog中对应的UserID的记录都会被删掉,但在ORM中总提示这种做法不合理,甚至报错!!我想知道是不是我做的不对



31 个解决方案

#1


先看看

#2


表User和UserGroup是一对多关系 

#3


因为UserGroup一个组里面有多个成员
UserLoginLog只不过是单独记录日志用的

#4


看看先

#5


表User主键UserID,表UserLoginLog外键UserID
你在删除User表中的信息时候
如果UserLoginLog有对应信息
这个是不能删除
除非你先删除UserLoginLog里面的信息
才能删除User中的信息

#6


级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能

#7


两个关系都可以说是一对多的关系吧

#8


User和UserLoginLog表User和UserGroup都是一对多关系

#9


引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?

#10


引用 8 楼 fredrickhu 的回复:
User和UserLoginLog表User和UserGroup都是一对多关系
用关系图设计吧!级联更新,级联删除(可选)

#11


USER和UserLoginLog是一对多
UserGroup和USER是一对多

#12


引用 9 楼 aspnet30 的回复:
引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?
用关系图设计

#13


引用 10 楼 soft_wsx 的回复:
引用 8 楼 fredrickhu 的回复:
User和UserLoginLog表User和UserGroup都是一对多关系


用关系图设计吧!级联更新,级联删除(可选)


关系图最后不也是建立了主外键吗?关系图实际上就是主外键的

#14


引用 9 楼 aspnet30 的回复:
引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?


这个可以考虑用级联删除或者触发器

#15


create table testA
(
 id int identity primary key,
 info varchar(100)
)
go 
create table testB
(
 id int identity primary key,
 fid int constraint fk_yy foreign key references testA(id) on update cascade on delete cascade,
 info varchar(100)
)
go
insert into testA values('a')
insert into testA values('b')
insert into testA values('c')
insert into testA values('d')
insert into testA values('e')
insert into testB values(1,'asdf')
insert into testB values(1,'asdf')
insert into testB values(1,'asdf')
insert into testB values(2,'asdf')
insert into testB values(2,'asdf')
insert into testB values(3,'asdf')
insert into testB values(3,'asdf')
insert into testB values(3,'asdf')
go


delete testa where id=2

select * from testb
/*
6
3 asdf 7
3 asdf 8
3 asdf
*/
最简单了!

#16


引用 11 楼 janely318 的回复:
USER和UserLoginLog是一对多
UserGroup和USER是一对多

支持,还有补充下,就是因为建立了主外键,所以你在删除用户时,要首先删除日志表的相关信息

#17


引用 11 楼 janely318 的回复:
USER和UserLoginLog是一对多
UserGroup和USER是一对多
up

#18


引用 14 楼 fredrickhu 的回复:
引用 9 楼 aspnet30 的回复:
引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?


这个可以考虑用级联删除或者触发器


怎么做级联删除?主外键不就是级联删除吗?关系图实际上也是会自动建立主外键的,那级联删除是用什么方法实现,除了触发器外

#19


上面不是有了吗?15楼

#20


引用 18 楼 aspnet30 的回复:
引用 14 楼 fredrickhu 的回复:
 引用 9 楼 aspnet30 的回复:
 引用 6 楼 bancxc 的回复:
 级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


 那我要做这个功能,怎么做呢?用触发器?


 这个可以考虑用级联删除或者触发器


 怎么做级联删除?主外键不就是级联删除吗?关系图实际上也是会自动建立主外键的,那级联删除是用什么方法实现,除了触发器外

参考15楼的代码

#21


user和userlogin是一对多关系,但不是典型意义上的一对多。只是存在不一定的关系,不象产品类型和产品那样,一种产品类型有多种产品,相对来说比较稳定,而Userlogin类似业务处理表,如入库处理,里包含产品ID,但不能简单归为一对多关系。
===============================================================
User和UserGroup情况有些复杂,实际应用中有不同情况。一般可以认为是一对多,usergroup为一,User为多。但也有一个组包括多个User,一个User可以在多个组中的情况,如MSSQL中的用户和用户组就是如此。这个时候,就是多对多的关系了。
================================================================
至于级联删除,可以在建立外键的时候设置的,至于性能影响,个人感觉应该不大的,因为你要达到这个目的,删除动作是不能少的。不论是级联删除,触发器和存储过程,应该在性能上都差不多。
ORM显示错误,可能是因为这种做法,象产品已经入库了,但你把产品删除了,就没有这个产品的库存了,不太符合要求吧。本身Userlogin就是个流水类型的表,如果不选级联删除,删除有登录记录的时候会出错的,提示无法删除。这样,更符合实际情况。在实际的做法中,可以采取用存储过程来实现的方式,可以选择将已在存在的登录数据转存至另外一个表,以供查询。如果没有这个需求,直接删除也示尝不可的。

#22


问题一:到底表User和UserLoginLog是一对多关系,还是表User和UserGroup是一对多关系 
都是一对多的关系.

问题二:我在表User和UserLoginLog建立主外键,sqlserver中没问题,但在ORM中总提示这种做法不合理,甚至报错 

SQL中,你的做法没问题.ORM是什么?不知道.

#23


至于你说的删除,可以使用触发器或者级联删除来实现.以下给出两种方法的实例,自己参考.

--触发器的操作1

create table 化验室纱组(本厂编号 int,客户 int,色号 int,纱支 int)
create table 化验室布组(本厂编号 int,客户 int,色号 int,布类 int)
go
create trigger my_trig on 化验室纱组 for insert ,update ,delete
as
if not exists(select 1 from inserted)
   delete 化验室布组 from deleted t where 化验室布组.本厂编号 = t.本厂编号 
else if not exists(select 1 from deleted) 
   insert into 化验室布组(本厂编号 ,客户 ,色号) select 本厂编号 ,客户 ,色号 from inserted
else
   update 化验室布组 set 客户 = t.客户 , 色号 = t.色号 from inserted t where 化验室布组.本厂编号 = t.本厂编号
go

--1、insert 对化验室纱组插入数据,然后查看化验室布组表的数据
insert into 化验室纱组 values(1 , 2 , 3 , 4)
insert into 化验室纱组 values(5 , 6 , 7 , 8)
go
select * from 化验室布组
/*
本厂编号        客户          色号          布类          
----------- ----------- ----------- ----------- 
1           2           3           NULL
5           6           7           NULL

(所影响的行数为 2 行)
*/

--2、update , 更改化验室纱组表中本厂编号=1的色号=6
update 化验室纱组 set 色号 = 6 where 本厂编号 = 1
go
select * from 化验室布组
/*
本厂编号        客户          色号          布类          
----------- ----------- ----------- ----------- 
1           2           6           NULL
5           6           7           NULL

(所影响的行数为 2 行)
*/

--3、delete 化验室纱组表中本厂编号=1的那条数据
delete from 化验室纱组 where 本厂编号 = 1
go
select * from 化验室布组
/*
本厂编号        客户          色号          布类          
----------- ----------- ----------- ----------- 
5           6           7           NULL

(所影响的行数为 1 行)
*/

drop table 化验室纱组 , 化验室布组


/*
标题:两表通过字段关联进行级联删除。
作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开) 
时间:2008-11-20
地点:广东深圳
*/

create table ta(id int not null)
create table tb(id int , aid int)
insert into ta values(1)
insert into ta values(2)
insert into tb values(1 , 1)
insert into tb values(2 , 2)
insert into tb values(3 , 1)
go

--一、查看原始数据
--ta表的原始数据
select * from ta
/*
id          
----------- 
1
2
*/
--tb表的原始数据
select * from tb
/*
id          aid         
----------- ----------- 
1           1
2           2
3           1
*/

--二、看看没有创建级联删除时的情况(删除ta表id=1的数据,看看是否影响tb表)
delete from ta where id = 1
select * from ta
/*
id          
----------- 
2
*/
select * from tb
/*
id          aid         
----------- ----------- 
1           1
2           2
3           1
*/

--三、恢复原始数据,创建级联删除,删除ta表id=1的数据,看看是否影响tb表
insert into ta values(1)
--为ta创建主健
alter table ta add constraint pk_ta_id primary key (id)
go
--为tb创建外健,并指定级联删除
alter table tb add constraint fk_tb_aid foreign key (aid) references ta(id) on delete cascade
go
delete from ta where id = 1
select * from ta
/*
id          
----------- 
2
*/
select * from tb
/*
id          aid         
----------- ----------- 
2           2
*/

--删除级联约束
alter table tb drop constraint fk_tb_aid
go
--删除测试表
drop table ta , tb
go

#24


该回复于2009-09-25 10:48:52被版主删除

#25


USER和UserLoginLog是一对多 
UserGroup和USER是一对多 

#26


关注

#27


gz

#28


只能回答第一个~
到底表User和UserLoginLog是一对多关系,还是表User和UserGroup是一对多关系-》
都是一对多的关系!

#29


mark

#30


恩 是的

ORM级联删除对不?

#31


引用 30 楼 jaylongli 的回复:
恩 是的

ORM级联删除对不?


ORM为什么会提示表User和UserLoginLog主外键关系存在问题,有什么问题吗

#1


先看看

#2


表User和UserGroup是一对多关系 

#3


因为UserGroup一个组里面有多个成员
UserLoginLog只不过是单独记录日志用的

#4


看看先

#5


表User主键UserID,表UserLoginLog外键UserID
你在删除User表中的信息时候
如果UserLoginLog有对应信息
这个是不能删除
除非你先删除UserLoginLog里面的信息
才能删除User中的信息

#6


级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能

#7


两个关系都可以说是一对多的关系吧

#8


User和UserLoginLog表User和UserGroup都是一对多关系

#9


引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?

#10


引用 8 楼 fredrickhu 的回复:
User和UserLoginLog表User和UserGroup都是一对多关系
用关系图设计吧!级联更新,级联删除(可选)

#11


USER和UserLoginLog是一对多
UserGroup和USER是一对多

#12


引用 9 楼 aspnet30 的回复:
引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?
用关系图设计

#13


引用 10 楼 soft_wsx 的回复:
引用 8 楼 fredrickhu 的回复:
User和UserLoginLog表User和UserGroup都是一对多关系


用关系图设计吧!级联更新,级联删除(可选)


关系图最后不也是建立了主外键吗?关系图实际上就是主外键的

#14


引用 9 楼 aspnet30 的回复:
引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?


这个可以考虑用级联删除或者触发器

#15


create table testA
(
 id int identity primary key,
 info varchar(100)
)
go 
create table testB
(
 id int identity primary key,
 fid int constraint fk_yy foreign key references testA(id) on update cascade on delete cascade,
 info varchar(100)
)
go
insert into testA values('a')
insert into testA values('b')
insert into testA values('c')
insert into testA values('d')
insert into testA values('e')
insert into testB values(1,'asdf')
insert into testB values(1,'asdf')
insert into testB values(1,'asdf')
insert into testB values(2,'asdf')
insert into testB values(2,'asdf')
insert into testB values(3,'asdf')
insert into testB values(3,'asdf')
insert into testB values(3,'asdf')
go


delete testa where id=2

select * from testb
/*
6
3 asdf 7
3 asdf 8
3 asdf
*/
最简单了!

#16


引用 11 楼 janely318 的回复:
USER和UserLoginLog是一对多
UserGroup和USER是一对多

支持,还有补充下,就是因为建立了主外键,所以你在删除用户时,要首先删除日志表的相关信息

#17


引用 11 楼 janely318 的回复:
USER和UserLoginLog是一对多
UserGroup和USER是一对多
up

#18


引用 14 楼 fredrickhu 的回复:
引用 9 楼 aspnet30 的回复:
引用 6 楼 bancxc 的回复:
级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


那我要做这个功能,怎么做呢?用触发器?


这个可以考虑用级联删除或者触发器


怎么做级联删除?主外键不就是级联删除吗?关系图实际上也是会自动建立主外键的,那级联删除是用什么方法实现,除了触发器外

#19


上面不是有了吗?15楼

#20


引用 18 楼 aspnet30 的回复:
引用 14 楼 fredrickhu 的回复:
 引用 9 楼 aspnet30 的回复:
 引用 6 楼 bancxc 的回复:
 级联删除 表User主键UserID,表UserLoginLog外键UserID ,删除User表中的信息时候的时候可以同时删除UserLoginLog的内容 但是好像这样用的很少 会影响性能


 那我要做这个功能,怎么做呢?用触发器?


 这个可以考虑用级联删除或者触发器


 怎么做级联删除?主外键不就是级联删除吗?关系图实际上也是会自动建立主外键的,那级联删除是用什么方法实现,除了触发器外

参考15楼的代码

#21


user和userlogin是一对多关系,但不是典型意义上的一对多。只是存在不一定的关系,不象产品类型和产品那样,一种产品类型有多种产品,相对来说比较稳定,而Userlogin类似业务处理表,如入库处理,里包含产品ID,但不能简单归为一对多关系。
===============================================================
User和UserGroup情况有些复杂,实际应用中有不同情况。一般可以认为是一对多,usergroup为一,User为多。但也有一个组包括多个User,一个User可以在多个组中的情况,如MSSQL中的用户和用户组就是如此。这个时候,就是多对多的关系了。
================================================================
至于级联删除,可以在建立外键的时候设置的,至于性能影响,个人感觉应该不大的,因为你要达到这个目的,删除动作是不能少的。不论是级联删除,触发器和存储过程,应该在性能上都差不多。
ORM显示错误,可能是因为这种做法,象产品已经入库了,但你把产品删除了,就没有这个产品的库存了,不太符合要求吧。本身Userlogin就是个流水类型的表,如果不选级联删除,删除有登录记录的时候会出错的,提示无法删除。这样,更符合实际情况。在实际的做法中,可以采取用存储过程来实现的方式,可以选择将已在存在的登录数据转存至另外一个表,以供查询。如果没有这个需求,直接删除也示尝不可的。

#22


问题一:到底表User和UserLoginLog是一对多关系,还是表User和UserGroup是一对多关系 
都是一对多的关系.

问题二:我在表User和UserLoginLog建立主外键,sqlserver中没问题,但在ORM中总提示这种做法不合理,甚至报错 

SQL中,你的做法没问题.ORM是什么?不知道.

#23


至于你说的删除,可以使用触发器或者级联删除来实现.以下给出两种方法的实例,自己参考.

--触发器的操作1

create table 化验室纱组(本厂编号 int,客户 int,色号 int,纱支 int)
create table 化验室布组(本厂编号 int,客户 int,色号 int,布类 int)
go
create trigger my_trig on 化验室纱组 for insert ,update ,delete
as
if not exists(select 1 from inserted)
   delete 化验室布组 from deleted t where 化验室布组.本厂编号 = t.本厂编号 
else if not exists(select 1 from deleted) 
   insert into 化验室布组(本厂编号 ,客户 ,色号) select 本厂编号 ,客户 ,色号 from inserted
else
   update 化验室布组 set 客户 = t.客户 , 色号 = t.色号 from inserted t where 化验室布组.本厂编号 = t.本厂编号
go

--1、insert 对化验室纱组插入数据,然后查看化验室布组表的数据
insert into 化验室纱组 values(1 , 2 , 3 , 4)
insert into 化验室纱组 values(5 , 6 , 7 , 8)
go
select * from 化验室布组
/*
本厂编号        客户          色号          布类          
----------- ----------- ----------- ----------- 
1           2           3           NULL
5           6           7           NULL

(所影响的行数为 2 行)
*/

--2、update , 更改化验室纱组表中本厂编号=1的色号=6
update 化验室纱组 set 色号 = 6 where 本厂编号 = 1
go
select * from 化验室布组
/*
本厂编号        客户          色号          布类          
----------- ----------- ----------- ----------- 
1           2           6           NULL
5           6           7           NULL

(所影响的行数为 2 行)
*/

--3、delete 化验室纱组表中本厂编号=1的那条数据
delete from 化验室纱组 where 本厂编号 = 1
go
select * from 化验室布组
/*
本厂编号        客户          色号          布类          
----------- ----------- ----------- ----------- 
5           6           7           NULL

(所影响的行数为 1 行)
*/

drop table 化验室纱组 , 化验室布组


/*
标题:两表通过字段关联进行级联删除。
作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开) 
时间:2008-11-20
地点:广东深圳
*/

create table ta(id int not null)
create table tb(id int , aid int)
insert into ta values(1)
insert into ta values(2)
insert into tb values(1 , 1)
insert into tb values(2 , 2)
insert into tb values(3 , 1)
go

--一、查看原始数据
--ta表的原始数据
select * from ta
/*
id          
----------- 
1
2
*/
--tb表的原始数据
select * from tb
/*
id          aid         
----------- ----------- 
1           1
2           2
3           1
*/

--二、看看没有创建级联删除时的情况(删除ta表id=1的数据,看看是否影响tb表)
delete from ta where id = 1
select * from ta
/*
id          
----------- 
2
*/
select * from tb
/*
id          aid         
----------- ----------- 
1           1
2           2
3           1
*/

--三、恢复原始数据,创建级联删除,删除ta表id=1的数据,看看是否影响tb表
insert into ta values(1)
--为ta创建主健
alter table ta add constraint pk_ta_id primary key (id)
go
--为tb创建外健,并指定级联删除
alter table tb add constraint fk_tb_aid foreign key (aid) references ta(id) on delete cascade
go
delete from ta where id = 1
select * from ta
/*
id          
----------- 
2
*/
select * from tb
/*
id          aid         
----------- ----------- 
2           2
*/

--删除级联约束
alter table tb drop constraint fk_tb_aid
go
--删除测试表
drop table ta , tb
go

#24


该回复于2009-09-25 10:48:52被版主删除

#25


USER和UserLoginLog是一对多 
UserGroup和USER是一对多 

#26


关注

#27


gz

#28


只能回答第一个~
到底表User和UserLoginLog是一对多关系,还是表User和UserGroup是一对多关系-》
都是一对多的关系!

#29


mark

#30


恩 是的

ORM级联删除对不?

#31


引用 30 楼 jaylongli 的回复:
恩 是的

ORM级联删除对不?


ORM为什么会提示表User和UserLoginLog主外键关系存在问题,有什么问题吗