例如,定記錄分頁搜索二郎Mnesia的
-record(item, {
id,
time,
status}).
我想搜索的1000年至1100年的項目,按時間排序,並status =:= <<"finished">>
有什麼建議?
例如,定記錄分頁搜索二郎Mnesia的
-record(item, {
id,
time,
status}).
我想搜索的1000年至1100年的項目,按時間排序,並status =:= <<"finished">>
有什麼建議?
這要看你的查詢是什麼樣子。如果你需要通過很多不同的列進行排序,那麼我會考慮使用SQL而不是Mnesia。
但是,如果您只需要您描述的那種查詢,您應該可以使用ordered_set
類型的表來處理排序,並且mnesia:select/4
可以處理分頁和約束。
下面是一些未經測試的代碼給你要點:
% time goes first because it's our primary sort key
-record(statuses, {time, id, status}).
...
create_table() ->
mnesia:create_table(statuses, [
{attributes, record_info(fields, statuses)}
,{type, ordered_set}
]).
-spec fetch_paged(integer()) -> {[tuple()], continuation()}|'$end_of_table'.
fetch_paged(PageSize) ->
MatchSpec = {#statuses{id = '$1', status = <<"finished">>, _ = '_'}, [], ['$1']},
mnesia:select(statuses, [MatchSpec], PageSize, read).
-spec next_page(continuation()) -> {[tuple()], continuation()}|'$end_of_table'.
next_page(Cont) ->
mnesia:select(Cont).
基本上,mnesia:select/4
給你結果的頁面和結果的下一個頁面的延續。沒有一種內置的方法可以像SQL數據庫那樣跳到第1000條結果,所以如果你需要這種功能,你可以自己構建它(保留一個時間索引,以便快速查找表中的第1000個時間)是{{2015,4,12},{23,53,8}}
,然後運行select
時使用,作爲一個後衛
我想,你應該使用mnesia:select/2
選擇哪個status =:= <<"finished">>
,那麼你可以使用lists:sort
通過time
對結果進行排序,最後你可以使用lists:sublist/3
的元素減去1000
到1100
的對象。
這裏是鏈接: http://www.erlang.org/doc/man/mnesia.html#select-2 http://www.erlang.org/doc/man/lists.html#sort-2 http://www.erlang.org/doc/man/lists.html#sublist-3
你可以使用dirty_match_object和select/2來獲得不錯的加速。因爲你可能不關心分頁用例的一致性。如果你的數據集特別大,你將用完RAM來做到這一點。你需要使用像dirty_/next/2之類的東西。 –
你可能使用QLC光標,這樣的事情:
order(table_name,[id,Direction]) ->
case Direction of
descent -> fun(A,B) -> A#table_name.id > B#table_name.id end;
ascent -> fun(A,B) -> A#table_name.id < B#table_name.id end
end;
select(universal,[Data_module,Table,Minor,Major,Order_by,Direction,Query]) ->
try
if
Minor == Major -> {error};
Minor == 0; Major == 0 -> {error};
true ->
case apply(Data_module,order,[Table,[Order_by,Direction]]) of
error -> {error};
Order ->
Transaction = fun() ->
Query = qlc:q([X||X <- mnesia:table(Table)]),
Handler = qlc:sort(Query,[{order,Order}]),
Cursor = qlc:cursor(Handler),
if
Minor == 1 ->
Result = qlc:next_answers(Cursor,Major),
qlc:delete_cursor(Cursor),
Result;
true ->
qlc:next_answers(Cursor,Minor-1),
Result = qlc:next_answers(Cursor,Major-Minor+1),
qlc:delete_cursor(Cursor),
Result
end
end,
mnesia:transaction(Transaction)
end
end
catch
Exception:Reason -> {error}
end.
QLC的手冊是在這裏Qlc:reference 但這種方式並不是最快在中等負載的情況下是足夠的(每秒鐘測試10000個連接),但是在內存可用空間內你會遇到更多的問題,你需要將它升高到
非常有幫助。不能有效地直接跳到第1000個結果的圖像 –
我對Mnesia的(相對缺乏經驗)印象是,您可以將其視爲NoSQL DB(完全有意義的是您不能請求第1000頁)或您可以將其視爲關係數據庫,但沒有您從SQL數據庫(例如Postgres)獲得的頂層接口。所以如果你想要Mnesia *和*這些圖層,你需要自己構建它們。 (這基本上是BlackMamba使用fetch/sort/slice操作進行的操作,想象一下將它寫入一個gen_server,它會做一些緩存操作。) –