postgresql 单向一对多关系

k2arahey  于 2022-11-23  发布在  PostgreSQL
关注(0)|答案(1)|浏览(173)

我有一个Recipe和一个Tag模型,目前,这个配方包含一个属于Tag的id数组:

@Entity()
    export class Recipe extends BaseEntity {
      @PrimaryGeneratedColumn('uuid')
      public id!: string;
    
      @Column({ type: 'varchar' })
      public title!: string;
    
      @Column({ type: 'varchar' })
      public description!: string;
    
      @Column({ type: 'simple-array', nullable: true })
      public tags: string[];

    }

@Entity()
export class Tag extends BaseEntity {
  @PrimaryGeneratedColumn('uuid')
  public id!: string;

  @Column({ type: 'varchar' })
  public name!: string;
}

然而,我目前还没有使用TypeORM的关系功能。我想知道,我该如何做呢?因为关系只以一种方式工作,即一个食谱有许多标签。

q5lcpyga

q5lcpyga1#

我可能是错的,但是我相信在默认情况下,您必须声明两种方式--即使您只打算使用关系的一个方向。
例如,你需要声明一个Recipe有许多Tags,你还必须建立TagRecipe的关系,即使你不打算使用它。
根据您的示例,您需要设置一对多和多对一关系。
由于Recipe将“拥有”标记,因此它将具有一对多:

// recipe.entity.ts

@OneToMany(() => Tag, (tag) => tag.recipe)
tags: Tag[];

则逆函数将如下所示:

// tag.entity.ts

@ManyToOne(() => Recipe, (recipe) => recipe.tags)
@JoinColumn({
    name: 'recipeId',
})
recipe: Recipe;

如果您正在考虑让多个recipe拥有相同的标记,则可能需要考虑using a many:many relationship

编辑

我想从技术上讲,你可以在一列中存储一个id数组来表示任何给定菜谱的标签。这里的问题是,如果你决定需要任何给定标签的进一步信息,会发生什么?
我是说,(这只是一个问题,所以要对所有这些持保留态度)。你正在弯曲你的食谱表,也存储关系信息。
我发现让我的“桶”(表)尽可能具体更有帮助。这会给我们留下:

recipes | tags | recipes_tags
-----------------------------

这样我的recipes表就只有食谱了,就是这样。“给予我所有食谱..."。标签也是一样的,“给我所有标签”
通过建立ManyToMany关系,我们告诉TypeORM这两个列是相关的--而不会“混淆”它们的底层数据。
如果您决定需要有关关系的更多信息,则可以在数据透视表上添加/删除列。此时,您仍将使用关系,而不是标记或配方,因此您的数据仍将是良好的和精简的!
另一个例子来自我自己的一个使用案例...
我有一个Activity和一个Resource,任何给定的资源都可以有一个或多个Activities
第一个
上面的代码生成了一个resources_activities_activities表。该表中包含:

resourceId | activityId
------------------------

我还可以在这里添加其他列。createdBystatus或特定于 * 关系 * 的其他列。该表中的每个条目都与活动 * 和 * 资源有关系--这很棒!
我知道我们已经超出了你最初的问题的范围,但我认为这是一个相当小的一步,为一个潜在的大胜利后。
请求获取资源时:example.com/resources/123我得到的结果如下:

"id": "123"
...
"activities": [
    {
        "id": "f79ce066-75ba-43bb-bf17-9e60efa65e25",
        "name": "Foo",
        "description": "This is what Foo is.",
        "createdAt": "xxxx-xx-xxxxx:xx:xx.xxx",
        "updatedAt": "xxxx-xx-xxxxx:xx:xx.xxx"
    }
]
...

同样,每当我得到一个活动,我也会得到与之相关的所有资源,在我的前端,我可以很容易地做一些像resource.activities这样的事情。

相关问题