ruby-on-rails - Rails 3 上的 Postgres 复合类型

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

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

问题是 Rails 的 ActiveRecord 对此没有 native 支持。

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

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

谢谢! :-)

最佳答案

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

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

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

在数据库方面我想到了一些事情:

  1. 由于这些类型将多个属性折叠为单个实体的方式,这种方法可能难以查询。这包括指定需要检查单个属性的特定值的条件。此外,如果这些复合类型中的任何一个包含键引用,则可能很难执行 CASCADE 选项。
  2. 如果性能成为问题,这种架构方法可能很难建立索引
  3. 这种模式方法似乎没有按照数据库应有的方式标准化。在提供的示例中,此复合数据应作为单独的表定义存在,并在父表中具有外键引用。

除非您想到的特定应用程序具有令人信服的好处,否则我建议采用更标准化的方法。而不是:

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

关于ruby-on-rails - Rails 3 上的 Postgres 复合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7348545/

相关文章:

ruby-on-rails - 如何创建这个模型元方法?

ruby-on-rails - Minitest ruby​​ 中的模拟或 stub 日期时间

ruby-on-rails - "stack level too deep"编译 Assets 时

postgresql - 使用 postgis 通过多边形路径创建一条中间线

mysql - Rails MySQL 无法单个批量插入

ruby-on-rails - 多范围唯一性验证

html - application.scss 没有风格化输入,textarea,select

database - 数据库如何对汉字进行排序?

sql - 在 Postgresql 中选择最近记录的更好方法

mysql - ActiveRecord index_by 重复键的优先级