PostgreSQL:如何标记数据库中的每个表?通用外键、数组列或其他方法

问题描述 投票:0回答:1

我目前正在设计一个 PostgreSQL 数据库,我需要在其中实现标记功能。本质上,我的数据库中任何表中的任何项目都可以通过键值标签进行标记,非常类似于 Azure 标签。

我正在考虑实现此功能的不同方法,但我对最佳方法感到困惑:

  1. 使用 Django 的通用外键
    我正在考虑的一种方法是利用 Django 的通用外键功能来创建一个通用的“标签”表,该表可以引用数据库中的任何其他表。这允许灵活性并避免复杂的逻辑。然而,可能存在一些缺点,例如性能影响或者如果没有 Django 的 ORM数据库就没有意义。
  2. 在单个表中手动实现,没有通用外键:
    另一种选择是手动实现“标签”表而不依赖 Django 的通用外键。我将创建一个单独的表,可以引用数据库中的任何其他表,但不使用正式的外键。这需要在数据库或后端存储一些逻辑,维护起来更加复杂。
  3. 每个表都有独立的交叉引用标签表
    或者,我可以为数据库中需要标记的每个表创建一个单独的表(即
    car_tags
    house_tags
    person_tags
    )。这种方法将确保清晰的分离和潜在的更好的性能,但它可能会导致冗余并增加查询和维护的复杂性。
  4. 在每个表中添加
    tags TEXT[]
    数组列
    在每个需要标记的表中引入一个“tags”数组列,而不是维护一个通用的“Tags”表。这简化了查询,但可能会限制灵活性和可扩展性。

哪种方法最适合此用例?我更关心数据库的可维护性和可扩展性,而不是性能。 如果这些不合适,您可以建议在 PostgreSQL 中实现灵活标记系统的任何最佳实践。

django postgresql foreign-keys many-to-many generic-foreign-key
1个回答
0
投票
  1. Django 的通用外键只是弱的、未强制/未保护的引用。

    Tags
    表将有另外两列,一列标识它所标记的 thing 的类型,另一列保存该事物的唯一标识符。

    无论有没有 Django ORM,从中找出头绪或尾部应该不会太难。这实际上是 PostgreSQL 在内部管理某些事物的方式:

    pg_class.relkind
    告诉您它列出的 thing 的类型,
    pg_class.oid
    标识特定的事物。当您在系统目录和视图中查找内容时,它将过滤到
    pg_class
    中保存的特定关系类型,并在
    oid
    上加入它。

  2. 您可以轻松地自己实现此功能,就像 Django 所做的那样:

    create table tag (
        id bigint generated by default as identity primary key,
        name text);
    create table tag_anything (
        tag_id bigint references tag(id),
        other_thing_type text,
        other_thing_id text);
    create view cat_tagged as 
        select cat.*,array_agg(tag.name) as tags
        from cat 
        join tag_anything ta 
          on ta.other_thing_type='cat'
         and ta.other_thing_id=cat.id
        join tag
          on tag.id=ta.tag_id;
        group by cat.id;
    

    一个问题是为这些事物设置视图和联接,另一个问题是每个“事物”可以使用不同的、可能是多列的主键,您需要将其映射到单个通用外键引用。

  3. 这是标准化的方法。如果您考虑 Django 的作用以及您可能尝试重现的内容,那么这只是每个事物一个表而已:上面示例中的
  4. tag_anything

    变为

    tag_cat
    ,丢失
    thing_type
    列并获得正确的外键引用,具有适当的类型。
    
    

  5. 到处添加
  6. text[]

    jsonb
    听起来就像一场噩梦。你会在各处重复标签并加重一切负担。
    
    

© www.soinside.com 2019 - 2024. All rights reserved.