私は、多数の同様のデータエントリを処理するアプリケーションのSQLベース(実際にはSQLite)ストレージを設計することに興味があります。この例では、チャットメッセージストレージにします。"データウェアハウス"のようなSQLiteストアデザイン
アプリケーションは、メッセージ参加者、タグなど、N対Nの関係を意味するすべてのデータをフィルタリングおよび分析する機能を提供する必要があります。
ので、スキーマ(スターの一種)は以下のようになります。
create table messages (
message_id INTEGER PRIMARY KEY,
time_stamp INTEGER NOT NULL
-- other fact fields
);
create table users (
user_id INTEGER PRIMARY KEY,
-- user dimension data
);
create table message_participants (
user_id INTEGER references users(user_id),
message_id INTEGER references messages(message_id)
);
create table tags (
tag_id INTEGER PRIMARY KEY,
tag_name TEXT NOT NULL,
-- tag dimension data
);
create table message_tags (
tag_id INTEGER references tags(tag_id),
message_id INTEGER references messages(message_id)
);
-- etc.
だから、すべての良い、よく、私はN対Nの寸法に基づいて分析操作やフィルタリングを実行する必要があるまで、 。 メッセージテーブル内の何百万行ものディメンション(この例では表示されている以上の数)があると、すべてのジョインはパフォーマンスが低下します。
例えば、私が選択したタグ、選択したユーザーおよび他の態様に基づいてフィルタリングされたデータ与えられ、各ユーザが参加したメッセージの数を分析したいと思います:
select U.user_id, U.user_name, count(1)
from messages as M
join message_participants as MP on M.message_id=MP.message_id
join user as U on MP.user_id=U.user_id
where
MP.user_id not in (/* some user ID's set */)
and M.time_stamp between @StartTime and @EndTime
and
-- more fact table fields filtering
and message_id in
(select message_id
from message_tags
where tag_id in (/* some tag ID's set */))
and
-- more N-to-N filtering
group by U.user_id
私はSQLに拘束していますし、具体的には、SQLiteです。そして私はテーブルのインデックスを使用します。
私はスキーマを改善するために何か方法はないでしょうか、それを解除するための巧妙な方法でしょうか?
多分、メッセージ行内の次元キーを索引付けする方法があります(FTS機能を使用すると考えましたが、テキスト索引を検索して、結果に参加するとパフォーマンスが向上します)。
正常に動作しないSQL文の例を挙げてください。 – trincot
@trincot例を参照 – galenus
すべての外部キーにインデックスを定義しましたか? – trincot