エンティティ属性値 (EAV) アプローチを使用して、患者/サンプル メタデータ テーブルを作成したいと考えています。
質問:属性に基づいて、値のさまざまな列タイプ (文字列、数値、または辞書テーブルへの外部キーなど) をどのように処理すればよいですか?
注: EAV アプローチを使用するかどうかを尋ねているわけではありません。私は他のSOの質問と参照を見て、これが私のユースケースに最適なアプローチであると信じています(たとえば、属性ごとに個別の列またはテーブルを作成したくない-数百に及ぶ可能性があります)。ただし、包括的な例を示して、他の設計を再考することは確かです。
代表的なデータ
患者/サンプル (エンティティ) は、複数のメタデータ属性(検査室の場所、生存率、腫瘍の種類など) を持つことができ、それぞれに異なる値の種類 (それぞれ 、*などVARCHAR
)があります。NUMBER
FOREIGN_KEY
*FOREIGN_KEY
は、この値の型が、値INTEGER
の辞書テーブルへの外部キー ID ( ) であることを意味します(例: 10 の可能な腫瘍型のリスト)。これらの値を正規化することは気にしないので、ラボの場所は可能です。しかし、腫瘍の種類にはある程度の検証が必要です。VARCHAR
私のテーブルレイアウトは次のようになります。
CREATE TABLE patients (
patient_id INTEGER CONSTRAINT pk_patients PRIMARY KEY,
patient_name VARCHAR2(50) NOT NULL
);
CREATE TABLE metadata_attributes (
attribute_id INTEGER CONSTRAINT pk_metadata_attributes PRIMARY KEY,
attribute_name VARCHAR2(50) NOT NULL,
attribute_value_type VARCHAR(50) NOT NULL -- e.g. VARCHAR, NUMBER, or ID
);
CREATE TABLE patient_metadata (
patient_id CONSTRAINT fk_pm_patients REFERENCES patients(patient_id) NOT NULL,
attribute_id CONSTRAINT fk_pm_attributes REFERENCES metadata_attributes(attribute_id) NOT NULL,
attribute_value ???
);
参照する列/テーブルを知るには、metadata_attributes テーブルに値の型を識別する列 (attribute_value_type)が必要だと思います。
可能なアプローチ
ここに私が考えることができる2つの可能なアプローチがあります。
アプローチ 1: 複数の列を持つ単一の EAV テーブル
値の種類ごとに 1 つずつ、patient_metadata テーブルに 3 つの異なる列を作成します。
CREATE TABLE patient_metadata (
patient_id CONSTRAINT fk_pm_patients REFERENCES patients(patient_id) NOT NULL,
attribute_id CONSTRAINT fk_pm_attributes REFERENCES metadata_attributes(attribute_id) NOT NULL,
attribute_varchar_value VARCHAR(50),
attribute_number_value NUMBER,
attribute_id_value CONSTRAINT fk_pm_values REFERENCES some_table_of_values(value_id)
);
アプローチ 2: 複数の EAV テーブル
値のタイプごとに 1 つずつ、3 つの異なる Patient_metadata テーブルを作成します。
CREATE TABLE patient_metadata_varchar (
patient_id CONSTRAINT fk_pm_patients REFERENCES patients(patient_id) NOT NULL,
attribute_id CONSTRAINT fk_pm_attributes REFERENCES metadata_attributes(attribute_id) NOT NULL,
attribute_value VARCHAR(50) NOT NULL
);
CREATE TABLE patient_metadata_number (
patient_id CONSTRAINT fk_pm_patients REFERENCES patients(patient_id) NOT NULL,
attribute_id CONSTRAINT fk_pm_attributes REFERENCES metadata_attributes(attribute_id) NOT NULL,
attribute_value NUMBER NOT NULL
);
CREATE TABLE patient_metadata_id (
patient_id CONSTRAINT fk_pm_patients REFERENCES patients(patient_id) NOT NULL,
attribute_id CONSTRAINT fk_pm_attributes REFERENCES metadata_attributes(attribute_id) NOT NULL,
attribute_value CONSTRAINT fk_pm_values REFERENCES some_table_of_values(value_id) NOT NULL
);
他のアプローチ?
そこに他のアプローチはありますか?
つまり、リレーショナル整合性を可能な限り尊重し、データベースが値の型を認識できるようにして、基本的な検証を実行できるようにしたいと考えています。ただし、上記の両方のアプローチでは、何らかの種類の手動の整合性チェックが必要になると思います (アプローチ 1 では、1 つの attribute_value 列のみが入力されていることを確認する必要があるなど)。
実行するクエリの種類は一般的です (たとえば、特定のメタデータ属性の値のリストを取得する、特定の患者 (エンティティ) およびメタデータ属性の値のリストを取得するなど)。照会する列またはテーブルを知るために、ほとんどの場合、値の型を照会する必要があると思います。これを回避する他の方法はありますか?
すべてのアプローチ (パフォーマンス、クエリ構造など) の長所と短所は何ですか?
初めてのポスターですので、事前に感謝し、フォーマットやさらなる明確化についてお気軽にコメントしてください!