n:m用户和访客之间的关系

dgsult0t  于 2021-07-29  发布在  Java
关注(0)|答案(3)|浏览(394)

我正在构建一个应用程序,可以将访客分配给现有用户。这些访客可以看到与他们相关联的用户的一些信息。
是的 N:M :
用户可以关联多个访客
访客可以关联到多个用户
在引擎盖下,它们被存放在同一张table上,它们之间唯一的区别就是它们所扮演的角色。
(我的真实表有更多的字段,如密码等。。。但这些与这个问题无关)

我需要创建这样一个表:

问题是 userId 以及 guestId 引用到同一列( id )的 Users table。
这可行吗?

qnakjoqk

qnakjoqk1#

用户只能是访客或主机。这就是为什么在用户表中有一个role列。
您的guests表连续包含两个用户,正如我在请求注解中提到的,我会调用它们 host_user_id 以及 guest_user_id 使他们的角色明显,并表明他们都是用户ID。
table的设计还可以。唯一的缺点是,您可能会错误地将一个主机设置为guest,而将一个guest设置为host,因为guests表不知道哪个是哪个,两者都只是用户id。如果您想让数据库在这方面保证一致性,这就变得有点复杂了。下面是一个处理此问题的设计:

create table users
(
  id         not null int,
  full_name  not null varchar(100),
  role       not null varchar(10),
  created_at not null timestamp,
  updated_at          timestamp,
  constraint pk_users primary key (id),
  constraint chk_users_role check (role in 'host', 'guest'),
  constraint unq_users_role unique (id, role)
);

create table guests
(
  host_user_id  not null int,
  host_role     not null varchar(10),
  guest_user_id not null int,
  guest_role    not null varchar(10),
  constraint pk_guests primary key (host_user_id, guest_user_id),
  constraint fk_guests_host foreign key (host_user_id, host_role) references users (id, role),
  constraint fk_guests_guest foreign key (guest_user_id, guest_role) references users (id, role),
  constraint chk_guests_host_role check (host_role = 'host'),
  constraint chk_guests_guest_role check (guest_role = 'guest')
);

这看起来不像以前那么好了 host_role 不断地 'host' 以及 guest_role 不断地 'guest' 在我们人类读者看来,这是多余的,但它保证了 host_user_id 指的是主机用户和 guest_user_id 对访客用户。

tquggr8v

tquggr8v2#

这就是你想要的吗?

create table users (
    userId int generated always as identity primary key,
    fullname varchar(255),
    . . .
);

create table guests (
    guestId int generated always as identity primary key,
    fullname varchar(255),
    . . 
);

create table userGuests (
     userGuestId int generated always as identity primary key,
     userId int references users(userId),
     guestId int references guests(guestId
);

然后,您可以将其加载为:
插入访客(全名,…)从role='guest'的旧用户中选择不同的全名;
插入用户(全名,…)从旧用户中选择不同的全名,其中role='user';

insert into userGuests (userId, guestId)
    select u.userId, g.userId
    from old_users ou join
         old_users og
         on ou.id = og.id join
         users u
         on ou.fullname = u.fullname join
         guests g
         on og.fullname = g.fullname
    where ou.role = 'user' and og.role = 'guest';

注意:这都使用了通用的sql语法,但它应该给出一个想法。

f8rj6qna

f8rj6qna3#

我不知道为什么它不起作用。不过,我会更改客人table的名称,只是为了更清楚地表明,它不容纳客人,而是容纳客人的关系。

相关问题