Сохранение реляционной целостности с Mnesia

В первом фрагменте кода вы объявляете factorials внутри блока цикла for, поэтому он не будет виден вне блока цикла for.

Он работает во втором фрагменте, потому что вы объявили его вне блока.

10
задан I GIVE TERRIBLE ADVICE 27 December 2008 в 17:43
поделиться

2 ответа

Я предпочитаю использовать GUID вместо того, чтобы автоувеличить ints как искусственные внешние ключи. Существует модуль Erlang uuid, доступный в GitHub, или можно использовать {now(), node()}, учитывая, что now/0 в документе говорится: "Также гарантируется, что последующие вызовы к этому BIF возвращают непрерывно увеличивающиеся значения".

Используя что-то, что может измениться, поскольку первичный ключ, кажется, мне плохая идея, независимая от системы баз данных.

Не забывайте, что Вы не должны нормализовать данные в Mnesia даже к первой нормальной форме; в Вашем примере я рассмотрел бы следующую структуру:

-record(user, {id, name, salt, pass_hash, email, entries}).
-record(entry, {id, title, body, slug, users}).

где entries и users списки идентификаторов. Конечно, это зависит от запросов, которые Вы хотите.

Править: зафиксированный, чтобы быть many-many вместо many-one.

9
ответ дан 3 December 2019 в 21:23
поделиться

Mnesia действительно поддерживает последовательности (автоувеличивающий целые числа) в форме mnesia:dirty_update_counter(Table, Key, Increment). Для использования его, Вам нужна таблица с двумя Ключами атрибутов и количеством. Несмотря на имя, dirty_update_counter является атомарным даже при том, что это не работает в транзакции.

Ulf Wiger сделал некоторую работу над обеспечением типичных функций RDBMS сверху mnesia в его rdbms пакете. Его код обеспечивает ограничения внешнего ключа, parametized индексы, ограничения значения поля и так далее. К сожалению, этот код не был обновлен за два года и вероятно будет трудным получить выполнение без довольно мало опыта Erlang.

При разработке для и использовании mnesia необходимо помнить, что mnesia не является реляционной базой данных. Это - транзакционное хранилище Ключа/Значения и намного легче использовать, когда Вы не нормализуете.

Если Ваши имена пользователей уникальны, Вы могли бы использовать схему:

-record(user, {name, salt, pass_hash, email}).
-record(entry, {posted, title, body, slug, user_name}).

Где posted erlang:now () время, когда статья загружается. user_name возможно, нуждался бы во вторичном индексе, если часто необходимо получать список всех статей для пользователя. Поскольку эти данные разделяются по двум таблицам, необходимо будет осуществить любые ограничения целостности в коде приложения (например, не принимая записи без допустимого user_name).

Каждое значение поля в mnesia может быть любым термином erlang, поэтому если Вы в замешательстве для уникального ключа на каком-либо конкретном поле, можно часто комбинировать некоторые поля, чтобы дать Вам значение, которое всегда будет уникально - возможно {Имя пользователя, 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).
8
ответ дан 3 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

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