新しいプロパティを追加する必要がある場合は、スキーマを変更する必要があります
それは実際に問題ですか?Oracleの新しいバージョンでは、列の追加がより安価で便利になりました。
ただし、新しいプロパティに対してDDLを実行する必要がないという意味で、システムを動的にする必要がある場合は、次の単純なEAV実装がおそらく良いスタートになります。
CREATE TABLE FOO (
FOO_ID INT PRIMARY KEY
-- Other fields...
);
CREATE TABLE FOO_PROPERTY (
FOO_ID INT REFERENCES FOO (FOO_ID),
NAME VARCHAR(50),
VALUE VARCHAR(50) NOT NULL,
CONSTRAINT FOO_PROPERTY_PK PRIMARY KEY (FOO_ID, NAME)
) ORGANIZATION INDEX;
ORGANIZATION INDEXに注意してください。テーブル全体が1つの大きなBツリーであり、テーブルヒープはまったくありません。同じFOO_IDに属するプロパティは物理的に近接して保存されるため、既知のFOO_IDのすべてのプロパティを取得するのは安価です(ただし、すべてのプロパティが同じ行にある場合ほど安価ではありません)。
また、次のことが適切かどうかを検討することもできます。
- FOO_PROPERTYにインデックスを追加します(たとえば、プロパティ名または値を検索する場合)。インデックス編成テーブルのセカンダリインデックスの追加コストに注意してください。
- FOO_PROPERTY PKの列の順序を切り替えます-主にプロパティ名を検索し、指定されたFOO_IDのすべてのプロパティを取得することはめったにない場合。これにより、インデックスの前縁が(狭い整数ではなく)比較的幅の広い文字列になるため、インデックスの圧縮も可能になります。
- VALUEには別のタイプを使用します(たとえば、 RAW、またはインラインBLOB / CLOBでさえ、パフォーマンスに影響を与える可能性がありますが、柔軟性が向上する可能性もあります)。あるいは、すべてを文字列に詰め込む代わりに、可能な値のタイプごとに個別のテーブルを用意することもできます。
- プロパティ「宣言」を独自のテーブルに分離します。このテーブルには2つのキーがあります。文字列NAMEのほかに、整数PROPERTY_IDもあり、NAMEの代わりにFOO_PROPERTYでFKとして使用できます(ストレージを節約しますが、JOINを増やす必要があります)。