Ruby on rails 博士后';轨道上的复合类型3

Ruby on rails 博士后';轨道上的复合类型3,ruby-on-rails,postgresql,activerecord,rails-postgresql,Ruby On Rails,Postgresql,Activerecord,Rails Postgresql,我发现了一个关于Postgres的新事物:复合类型。我真的很喜欢这种方法,它将对我非常有用 问题是rails的ActiveRecord没有对此的本机支持 你有没有将Postgres的复合类型与Rails一起使用过?这是一次很好的体验,还是您更喜欢为嵌套数据创建新模型的常用方法 Tks!:-) 这是PostgreSQL的一个有趣功能,但是我还没有机会使用它 在Rails方面,我想到了一些事情: ActiveRecord很难格式化查询这些对象所需的SQL。您可能需要编写自定义SQL来考虑特殊语法

我发现了一个关于Postgres的新事物:复合类型。我真的很喜欢这种方法,它将对我非常有用

问题是rails的ActiveRecord没有对此的本机支持

你有没有将Postgres的复合类型与Rails一起使用过?这是一次很好的体验,还是您更喜欢为嵌套数据创建新模型的常用方法


Tks!:-)

这是PostgreSQL的一个有趣功能,但是我还没有机会使用它

在Rails方面,我想到了一些事情:

  • ActiveRecord很难格式化查询这些对象所需的SQL。您可能需要编写自定义SQL来考虑特殊语法
  • ActiveRecord将无法执行自定义类型的隐式转换。当试图通过ActiveRecord访问属性时,这可能会出现问题。您可以扩展PostgreSQL adapter for ActiveRecord,将这些特殊数据类型转换为自定义类,但这是一种非传统的方法
  • 在数据库方面会想到一些事情:

  • 由于这些类型将多个属性折叠为单个实体的方式,因此这种方法可能很难查询。这包括指定需要为特定值检查单个属性的条件。此外,如果这些组合类型中的任何一个包含键引用,则执行级联选项可能会很困难
  • 如果性能成为问题,这种模式方法可能很难索引
  • 这种模式方法似乎没有按照数据库应该的方式进行规范化。在提供的示例中,此复合数据应作为单独的表定义存在,并在父表中具有外键引用
  • 除非您心目中的特定应用程序有令人信服的好处,否则我建议采用更规范化的方法。而不是:

    CREATE TYPE inventory_item AS (
        name            text,
        supplier_id     integer,
        price           numeric
    );
    
    CREATE TABLE on_hand (
        item      inventory_item,
        count     integer
    );
    
    INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
    
    您可以通过执行以下操作获得类似的结果,同时保持对ActiveRecord的完全支持,而无需扩展Postgres适配器或创建自定义类:

    CREATE TABLE inventory_item (
        id              integer,
        name            text,
        supplier_id     integer,
        price           numeric
    );
    
    CREATE TABLE on_hand (
        inventory_item_id     integer,
        count                 integer
    );
    
    INSERT INTO inventory_item VALUES ('fuzzy dice', 42, 1.99) RETURNS INTEGER;
    INSERT INTO on_hand VALUES (<inventory_item_id>, 1000);
    
    CREATE TABLE inventory\u项目(
    id整数,
    名称文本,
    供应商id整数,
    价格数字
    );
    在手上创建表格(
    库存\项目\ id整数,
    计数整数
    );
    在库存中插入项目值('fuzzy dice',42,1.99)返回整数;
    插入现有值(,1000);
    
    的确如此。这个解决方案乍一看有点冗长,但我想复合类型在很多情况下都是需要避免的。