Erlang Mnesia, Эквивалентный из Выбора SQL, ОТ ГДЕ Поле В (value1, value2, value3, …)

У меня есть mnesia таблица с полями, говорят что f1, f2, f3. Теперь, если бы я должен был выбрать все строки со значением поля как V1, то я использовал бы mnesia:select и спецификации соответствия или простое mnesia:match_object. Теперь я должен выбрать все строки, которые имеют V1, V2, V3... или Vn (список произвольной длины) как значение для поля f1. В SQL я сделал бы что-то как

SELECT * FROM tablename WHERE f3 IN (V1, V2, V3, ... , Vn)

Как я делаю это в mnesia?

7
задан ErJab 26 May 2010 в 05:57
поделиться

3 ответа

И для решения этой проблемы со спецификацией соответствия, если QLC оценивается как недостаточно эффективный.

> ets:fun2ms(fun ({_,X}=E) when X == a -> E end).
[{{'_','$1'},[{'==','$1',a}],['$_']}]

ets: fun2ms - это преобразование синтаксического анализа, которое может преобразовывать некоторые функции в значения matchspec. Я использую его как быстрый способ получить нужный мне матч. Мы получаем список со спецификацией совпадений, который находит кортеж, в котором вторым элементом является a. Мы можем повторить это для других ключей.

Итак, давайте заполним таблицу ets чем-нибудь, чтобы попробовать это, а затем создадим спецификацию соответствия, которая сопоставляет только элементы со вторым элементом как 'a' или 'c'. (Я ввожу это

ets:new(foo, [named_table]).

ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]).

Vs = [a,c].

MS = [{{'_','$1'},[{'==','$1',V}],['$_']} || V <- Vs].

ets:select(foo, MS).

Когда я запускаю это, я получаю:

[{1,a},{3,c}]
6
ответ дан 6 December 2019 в 21:10
поделиться

Если вам нужны «сложные» запросы, QLC - это краткий способ их сформулировать. QLC - это синтаксическое преобразование, которое позволяет использовать синтаксис понимания списка в различных таблицах, включая таблицы мнезии.

Вы должны иметь следующее включение, поскольку оно включает синтаксическое преобразование, которое делает возможным QLC в этом исходном файле.

-include_lib("stdlib/include/qlc.hrl").

Базовая форма запроса выглядит следующим образом: создается дескриптор запроса и затем выполняется оценка запроса.

QH = qlc:q([X || X <- Xs]),
qlc:eval(QH).

Затем вы можете использовать http://www.erlang.org/doc/man/mnesia.html#table-1 , чтобы получить таблицу QLC на стороне в таблице мнезии. Таким образом, ваш запрос может быть реализован следующим образом:

Vs = [V1,V2,...Vn],
QH = qlc:q([X || X <- mnesia:table(tablename), 
                 lists:member(X#tablename.f3, Vs)]),
qlc:eval(QH).

Для этого требуется сканирование таблицы, что не очень эффективно. Если у вас есть индекс в столбце f3, вы можете вместо этого повернуть его и запросить сначала записи с f3 = V1, затем V2 и т. Д. ... и объединить результаты.

PS

Альтернативой является создание довольно сложной спецификации соответствия из вашего списка V-значений и запуск mnesia: select.

2
ответ дан 6 December 2019 в 21:10
поделиться

Кристиан указал на хорошее решение, но его можно сделать немного проще

2> ets:fun2ms(fun ({_,a}=E) -> E end).             
[{{'_',a},[],['$_']}]

поэтому для вас можно сделать более простую спецификацию

4> ets:new(foo, [named_table]).
foo
5> ets:insert(foo, [{1,a},{2,b},{3,c},{4,d}]).
true
6> Vs = [a,c].
[a,c]
7> MS = [{{'_',V},[],['$_']} || V <- Vs].                
[{{'_',a},[],['$_']},{{'_',c},[],['$_']}]
8> ets:select(foo, MS).
[{1,a},{3,c}]
4
ответ дан 6 December 2019 в 21:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: