アルバムと曲の名前のカタログがあります。この曲には、アルバムテーブルへの外部キーがあります。私は次のようなクエリを期待しています:
SELECT * FROM song s
JOIN album a ON a.id = s.album_id
WHERE LOWER(CONCAT_WS(' ', album.name, song.name) = LOWER('Meteora Breaking The Habit')
上記のタイプの検索用語にインデックスを作成したいのですが、複数のテーブルにまたがるインデックスを作成できないようです。この場合、テーブルを非正規化し、曲とアルバムの名前を1つのテーブルに入れるのは理にかなっていますか、それともより良いアプローチがありますか?
参照表:
CREATE TABLE album (
id SERIAL PRIMARY KEY,
name text NOT NULL
);
CREATE TABLE song (
id SERIAL PRIMARY KEY,
name text NOT NULL,
album_id integer NOT NULL,
CONSTRAINT album_id_fk FOREIGN KEY (album_id) REFERENCES album (id)
);
P.S.理解のために、クエリが最初に曲名、後でアルバム名になる可能性があるという事実を無視しています。また、そのクエリを無視すると、バンド名も含まれる可能性があります。クライアントから送信されるクエリの形式はalbum.name + ' ' + song.name
。
クエリのLOWER('Meteora Breaking The Habit')
部分を、制御できないソースから取得している場合は、曲/アルバムテーブルの構造を維持することをお勧めします(ただし、song
テーブルからalbum_id
を削除します)。 3番目のテーブルを含める:
CREATE TABLE ALBUM_SONG (
album_id,
song_id,
album_song_name -- this would be album.name || song.name
)
これは基本的に、M-M関係の2つの間の結合テーブルです(「なぜなら、同じ曲が複数のアルバムに含まれている可能性があるからです)。
次に、LOWER(album_song_name)
の結合テーブルにインデックスを付けてクエリを実行できます。
私のアドバイスと経験-データベースを非正規化しないでください。代わりにそれを再設計し、少なくとも1NF、2NF、および3NFを使用します。私はあなたが使っているテーブルにあまり精通していません。 PKは両方で同じように見えると考えてください。アルバムのPKは曲のPKと同じである必要がありますか?曲はアルバムに依存しているので、ここでは必要ないと思います。これらは1つのテーブルに入れるべきだと思います。アルバムと曲はアーティストに部分的にのみ依存しているため、テーブルで識別される必要があるのはアーティストであり、これらは別のテーブルのアルバムIDにリンクする必要がありますか?私は学位を取得し、リレーショナルデータベースの使用を開始したばかりなので、ここでの支援と学習を望んでいます。