【问题标题】:designing three dimensional relationships with ORM (TypeORM)用 ORM (TypeORM) 设计三维关系
【发布时间】:2020-02-19 17:27:23
【问题描述】:

我尝试创建一个包含用户、组、文档和权限的数据库架构。

  • 用户可以加入多个群组
  • 组可以有多个用户
  • 用户可以拥有文档权限
  • 群组可以拥有文档权限
  • 权限可以是任何东西,不仅仅适用于文档

我试图为此创建一个小图形

我开始设计实体

用户

@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[];
}

@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[];
}

文档

@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[];
}

当涉及到文档的权限时,您会看到 3 个表、用户/组、文档和权限之间存在关系。

  1. 我将 TypeORM 用于 REST API (NestJs),但我不确定权限是否为实体。由于我正在设计 REST 端点,这个权限实体将是多个端点的共享实体。

  2. 如何扩展我的实体以获得这些权限?

...也许你会想出更好的数据库设计:)

【问题讨论】:

    标签: javascript typescript orm nestjs typeorm


    【解决方案1】:

    在这种情况下,建议手动处理它,创建一个实体类 CrossGroupDocumentPermissionEntity 并为每个关系添加一个 ManyToOne,在 Document、Group、User 的另一侧添加一个 OneToMany 关系here 是一个示例在带有自定义字段的多对多中使用

    编辑:

    用户

    @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[];
    }
    

    @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[];
    }
    

    权限

    @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[];
    }
    

    文档

    @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[];
    }
    

    Cross_User_Document_Permission

    @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;
    }
    

    【讨论】:

    • @拉尔夫谢谢。所以你会说 Permission 不应该是一个实体?
    • 不不我指的是右边的三维关系而不是使用 ManyToMany 装饰器手动创建它 oneToMany ManyToOne 你可以同时拥有三个三维关系但@ManyToMany 强制你只有一个表有两个关系,如果你需要我可以给你一个右边关系的例子
    • 关于权限,如果用户总是有一个组,也许你不需要 Cross_User_Document_Permission 我相信你需要 Permission 表,因为你可以区分权限,除非你打算在每个文档中使用 ACL
    • 一个小例子会很棒 :) 用户可能没有组成员身份
    猜你喜欢
    • 2021-10-27
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2021-07-06
    • 1970-01-01
    • 1970-01-01
    • 2019-10-22
    • 2020-08-09
    相关资源
    最近更新 更多