У меня есть 3 таблицы: Mysqlбулевы операции по MySQL результаты
[block_value]
- id_block_value
- file_id
[метаданные]
- id_metadata
- metadata_name
[metadata_value]
- meta_id
- значение
- blockvalue_id
В этих таблицах Ther е являются пары: 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 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
, поскольку у нас нет intersect
в Mysql, я попытался A and file_id in(B)
, но посмотрите на perfs (> 4 млн) ...
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)
Итак ... что мне теперь делать? Есть ли лучший способ для булевых операций? Любой отзыв? Я что-то пропустил?
EDIT: какие данные выглядит следующим образом:
Эта база данных содержит строку в FILE
таблице для каждого аудио/видео файла, вставленного:
- 10, /path/to/file.ts
- 11, /path/to/file2.mpeg
Существует ряд в METADATA
таблице для каждого потенциального информация:
- 301, высота
- 302, расширение файла
Затем строка в BLOCK
таблицы определяют контейнер:
- 101, видео
- 102, аудио
- 104, General
Файл может иметь несколько блоков метаданных у BLOCK_VALUE
таблица содержит примеры блоков:
- 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 General (104)
Значения сохраняются в METADATA_VALUE
- 302, 406, «TS "// расширение файла, общее
- 301, 402, "+1080" // высота, видео 1
- 301, 403, "720" // высота, видео 2
- 301, 404, "352"//высота, Видео 3
Впечатляющий. Хотел бы я дать вам больше репутаций! Спасибо миллион за ваше время и ваши навыки (и спасибо ChrisCamp, который тоже очень старался) – Cyrille