javascript - designe tredimensjonale relasjoner med ORM (TypeORM)


Jeg prøvde å lage et databaseskjema med brukere, grupper, dokumenter og tillatelser.

  • brukere kan bli med i flere grupper
  • grupper kan ha flere brukere
  • brukere kan ha tillatelser for dokumenter
  • grupper kan ha tillatelser for dokumenter
  • tillatelser kan være hva som helst, ikke bare for dokumenter

Jeg prøvde å lage en liten grafikk for det

Jeg begynte å designe enhetene

Bruker

@Entity('User')
export class UserEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.users)
  @JoinTable()
  groups: GroupEntity[];

  @ManyToMany((type: any) => DocumentEntity, (document: DocumentEntity) => document.users)
  @JoinTable()
  documents: DocumentEntity[];
}

Gruppe

@Entity('Group')
export class GroupEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.groups)
  users: UserEntity[];

  @ManyToMany((type: any) => DocumentEntity, (document: DocumentEntity) => document.groups)
  @JoinTable()
  documents: DocumentEntity[];
}

Dokument

@Entity('Document')
export class DocumentEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.documents)
  users: UserEntity[];

  @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.documents)
  groups: GroupEntity[];
}

Når det gjelder tillatelser for dokumenter, vil du se at relasjonen finnes mellom 3 tabeller: brukere/grupper, dokumenter og tillatelser.

  1. Jeg bruker TypeORM for REST-APIer (NestJs), og jeg er ikke sikker på om en tillatelse er en enhet. På grunn av at jeg designer REST-endepunkter, vil denne tillatelsesentiteten være en delt enhet på tvers av flere endepunkter.

  2. Hvordan må jeg utvide mine enheter for disse tillatelsene?

... og kanskje du kan komme opp med et bedre databasedesign :)

Svar #1

I dette tilfellet anbefales det å håndtere det manuelt, lage en entitetsklasse CrossGroupDocumentPermissionEntity og legge til en ManyToOne for hver relasjon, og på den andre siden, på Document, Group, User, legge til en OneToMany-relasjon. Her er et eksempel på bruk i ManyToMany med egne felt.

Rediger :

Bruker

@Entity('User')
export class UserEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => GroupEntity, (group: GroupEntity) => group.users)
  @JoinTable()
  groups: GroupEntity[];

  @OneToMany((type: any) => CrossUserDocumentPermissionEntity, (documentPermission: CrossUserDocumentPermissionEntity) => documentPermission.user)
  documentPermissions: CrossUserDocumentPermissionEntity[];
}

Gruppe

@Entity('Group')
export class GroupEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @ManyToMany((type: any) => UserEntity, (user: UserEntity) => user.groups)
  users: UserEntity[];

  @OneToMany((type: any) => CrossGroupDocumentPermissionEntity, (documentPermission: CrossGroupDocumentPermissionEntity) => documentPermission.group)
  documentPermissions: CrossGroupDocumentPermissionEntity[];
}

Tillatelse

@Entity('Permission')
export class PermissionEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @OneToMany((type: any) => CrossUserDocumentPermissionEntity, (userDocument: CrossUserDocumentPermissionEntity) => userDocument.permission)
  usersDocuments: CrossUserDocumentPermissionEntity[];

  @OneToMany((type: any) => CrossGroupDocumentPermissionEntity, (groupDocument: CrossUserDocumentPermissionEntity) => groupDocument.permission)
  GroupDocuments: CrossGroupDocumentPermissionEntity[];
}

Dokument

@Entity('Document')
export class DocumentEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @OneToMany((type: any) => CrossUserDocumentPermissionEntity, (userPermission: CrossUserDocumentPermissionEntity) => userPermission.document)
  usersPermissions: CrossUserDocumentPermissionEntity[];

  @OneToMany((type: any) => CrossGroupDocumentPermissionEntity, (groupPermission: CrossUserDocumentPermissionEntity) => groupPermission.document)
  GroupPermissions: CrossGroupDocumentPermissionEntity[];
}

Tvær_bruker_dokument_tillatelse

@Entity('Cross_User_Document_Permission')
export class CrossUserDocumentPermissionEntity {
  @PrimaryColumn()
  userId: string;

  @PrimaryColumn()
  permissionId: string;

  @PrimaryColumn()
  documentId: string;

  @ManyToOne((type: any) => UserEntity, (user: UserEntity) => user.documentPermission)
  user: UserEntity;

  @ManyToOne((type: any) => DocumentEntity, (document: DocumentEntity) => document.userPermission)
  document: DocumentEntity;

  @ManyToOne((type: any) => PermissionEntity, (permission: PermissionEntity) => permission.userDocument)
  permission: PermissionEntity;
}