私は3つのMysqlテーブルを持っています:
[ブロック値]
- id_block_value
- file_id
[メタデータ]
- id_metadata
- メタデータ名
[メタデータ値]
- メタ ID
- 価値
- blockvalue_id
これらのテーブルには、ペアがあります: metadata_name
=value
そして、ペアのリストはブロック ( id_block_value
)に入れられます
(A)高さ = 1080 が必要な場合:
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "height" and value = "1080");
+---------+
| file_id |
+---------+
| 21 |
| 22 |
(...)
| 6962 |
(...)
| 8146 |
| 8147 |
+---------+
794 rows in set (0.06 sec)
(B)ファイル拡張子 = mpeg が必要な場合:
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "file extension" and value = "mpeg");
+---------+
| file_id |
+---------+
| 6889 |
| 6898 |
| 6962 |
+---------+
3 rows in set (0.06 sec)
しかし、私が望むなら:
- AとB
- AまたはB
- BではなくA
じゃあ何が一番いいのかわからない。
についてA or B
は、どれがうまくいくか試しA union B
てみました。
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "height" and value = "1080")
UNION
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "file extension" and value = "mpeg");
+---------+
| file_id |
+---------+
| 21 |
| 22 |
| 34 |
(...)
| 6889 |
| 6898 |
+---------+
796 rows in set (0.13 sec)
についてA and B
は、Mysql にはないのでintersect
、試しA and file_id in(B)
てみましたが、perfs を見てください (>4mn)...
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "height" and value = "1080")
and file_id in(
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "file extension" and value = "mpeg"));
+---------+
| file_id |
+---------+
| 6962 |
+---------+
1 row in set (4 min 36.22 sec)
私も試してみB and file_id in(A)
ましたが、どちらの方がはるかに優れていますが、どちらを最初に置くべきかわかりません。
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "file extension" and value = "mpeg")
and file_id in(
SELECT DISTINCT file_id
FROM metadata_value MV
INNER JOIN metadata M ON MV.meta_id = M.id_metadata
INNER JOIN block_value BV ON MV.blockvalue_id = BV.id_block_value
WHERE (metadata_name = "height" and value = "1080"));
+---------+
| file_id |
+---------+
| 6962 |
+---------+
1 row in set (0.75 sec)
それで... 私は今何をしますか?ブール演算のより良い方法はありますか? ヒントはありますか?私は何か見落としてますか?
編集:データはどのように見えますか:
このデータベースには、FILE
挿入された各オーディオ/ビデオ ファイルのテーブルの行が含まれています。
- 10、/path/to/file.ts
- 11、/path/to/file2.mpeg
METADATA
表には、潜在的な情報ごとに行があります。
- 301、高さ
- 302、ファイル拡張子
次に、BLOCK
テーブルの行でコンテナーを定義します。
- 101、ビデオ
- 102、オーディオ
- 104、一般
ファイルにはメタデータの複数のブロックを含めることができ、BLOCK_VALUE
テーブルには BLOCKS のインスタンスが含まれます。
- 402、101、10 // ビデオ 1
- 403、101、10 // ビデオ 2
- 404, 101, 10 // ビデオ 3
- 405、102、10 // オーディオ
- 406、104、10 // 一般
この例では、ファイル 10 に 5 つのブロックがあります: 3 つのビデオ (101) + 1 つのオーディオ (102) + 1 つの一般 (104)
値は次の場所に格納されますMETADATA_VALUE
- 302, 406, "ts" // ファイル拡張子、一般
- 301, 402, "1080" // 高さ, ビデオ 1
- 301, 403, "720" // 高さ, ビデオ 2
- 301, 404, "352" // 高さ, ビデオ 3