これはPostgreSQLの興味深い機能ですが、私はそれを使用する機会がありませんでした。
Rails側で頭に浮かぶことがいくつかあります。
- ActiveRecordは、これらのオブジェクトをクエリするために必要なSQLをフォーマットするのに苦労するでしょう。特別な構文を考慮に入れるには、おそらくカスタムSQLを作成する必要があります。
- ActiveRecordは、カスタムタイプの暗黙的なキャストを行うことができなくなります。これは、ActiveRecordを介して属性にアクセスしようとするときに問題になる可能性があります。ActiveRecord用のPostgreSQLアダプターを拡張して、これらの特別なデータ型をカスタムクラスにキャストできますが、これは従来とは異なるアプローチです。
データベース側で頭に浮かぶことがいくつかあります。
- これらのタイプが複数の属性を単一のエンティティに折りたたむ方法のため、このアプローチはクエリが難しい場合があります。これには、特定の値について個々の属性をチェックする必要がある条件の指定が含まれます。さらに、これらの複合型のいずれかにキー参照が含まれている場合、CASCADEオプションの実行が困難になる可能性があります。
- パフォーマンスが問題になる場合、このスキーマアプローチはインデックス作成が難しい可能性があります
- このスキーマアプローチは、データベースのように正規化されていないようです。提供されている例では、この複合データは、親テーブルに外部キー参照を含む別個のテーブル定義として存在する必要があります。
あなたが考えている特定のアプリケーションに説得力のある利点がない限り、私はより正規化されたアプローチを提案します。それ以外の:
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);
Postgresアダプターを拡張したり、カスタムクラスを作成したりせずに、ActiveRecordの完全なサポートを維持しながら、次の手順を実行することで、同様の結果を得ることができます。
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);