Mnesia поддерживает последовательности (автоинкрементные целые числа) в форме mnesia:dirty_update_counter(Table, Key, Increment)
. Для его использования вам понадобится таблица с двумя атрибутами Key и Count. Несмотря на название, dirty_update_counter является атомарным, даже если он не выполняется внутри транзакции.
Ульф Вигер проделал определенную работу по предоставлению типичных функций СУБД поверх mnesia в своем пакете rdbms . Его код обеспечивает ограничения внешнего ключа, параметризованные индексы, ограничения значений полей и так далее. К сожалению, этот код не обновлялся в течение двух лет, и, вероятно, его будет сложно запустить без большого опыта работы с Erlang.
При разработке и использовании mnesia вы должны помнить, что mnesia не является реляционной базой данных. Это транзакционное хранилище ключей / значений, и его гораздо проще использовать, когда вы не нормализуете.
Если ваши имена пользователей уникальны, вы можете использовать схему:
-record(user, {name, salt, pass_hash, email}).
-record(entry, {posted, title, body, slug, user_name}).
Где posted
- это erlang: now () время загрузки статьи. user_name
может понадобиться вторичный индекс, если вам часто нужно получить список всех статей для пользователя. Поскольку эти данные разделены на две таблицы, вам придется применять любые ограничения целостности в коде приложения (например, не принимать записи без действительного имени пользователя).
Каждое значение поля в mnesia может быть любым термином Эрланга, поэтому, если вы не знаете, какой уникальный ключ у какого-либо отдельного поля, вы можете комбинировать некоторые поля, чтобы получить значение, которое всегда будет уникальным - возможно {Имя пользователя, DatePosted, TimePosted}. Mnesia позволяет искать частичные ключи с помощью mnesia:select(Table, MatchSpec)
. MatchSpecs довольно сложно написать вручную, поэтому помните, что ets:fun2ms/1
может преобразовать функцию psuedo erlang в matchspec для вас.
В этом примере fun2ms генерирует нам matchspec для поиска в таблице записей в блоге -record(entry, {key, title, slug, body}).
, где ключ {Username, {Year, Month, Day}, {Hour, Minute, Second}}
- имя пользователя автора и дата и время публикации статьи. Приведенный ниже пример извлекает заголовки всех сообщений в блоге по TargetUsername
в декабре 2008 года.
ets:fun2ms(fun (#entry{key={U, {Y,M,_D}, _Time}, title=T})
when U=:=TargetUsername, Y=:=2008, M=:=12 ->
T
end).