Postgres在Rails上的复合类型3

时间:2011-09-08 13:08:44

标签: ruby-on-rails postgresql activerecord rails-postgresql

我发现了一个关于Postgres的新东西:复合类型。我非常喜欢这种方法,对我来说非常有用。

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

你曾经使用过Rails的Postgres复合类型吗?是一种很好的体验还是您更喜欢为这种嵌套数据创建新模型的常用方法?

http://www.postgresql.org/docs/8.4/static/rowtypes.html

韩国社交协会! : - )

1 个答案:

答案 0 :(得分:4)

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

Rails方面会想到一些事情:

  1. ActiveRecord将很难格式化查询这些对象所需的SQL。您可能必须编写自定义SQL以考虑特殊语法。
  2. ActiveRecord将无法隐式转换自定义类型。尝试通过ActiveRecord访问属性时,这可能会有问题。您可以扩展ActiveRecord的PostgreSQL适配器以将这些特殊数据类型转换为自定义类,但这是一种非传统方法。
  3. 数据库方面会想到一些事情:

    1. 由于这些类型将多个属性折叠为单个实体的方式,这种方法可能难以查询。这包括指定需要检查特定值的单个属性的条件。此外,如果这些复合类型中的任何一个包含键引用,则可能难以执行CASCADE选项。
    2. 如果性能成为问题,这种模式方法可能难以编制索引
    3. 这种模式方法似乎没有以数据库的方式规范化。在提供的示例中,此复合数据应作为单独的表定义存在,并在父表中使用外键引用。
    4. 除非您考虑的具体应用具有令人信服的好处,否则我建议采用更加规范化的方法。而不是:

      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);