2009-06-30 191 views
4

我正在開發一個需要很多數據庫寫入的Erlang應用程序。除了主鍵之外,我的模式還有一個強制執行唯一約束的屬性。Mnesia中的唯一約束條件

說我有一個ID,一個unique_constraint_field和其他一些字段。由於沒有其他行應具有我要更新的unique_constraint_field值的值,因此我需要現在更新DB中對應於唯一ID的行。由於更新量大(每次更新只會影響1行),我需要執行(也需要低延遲),我依靠主鍵和該屬性的唯一約束來捕獲重複,而不是使用子查詢的更新語句。這允許我在單個查詢中執行更新(這發生在95%的時間內),而在剩餘的5%中,我可以捕獲異常以採取有關主鍵或唯一屬性違規的必要操作。

我目前使用ODBC mysql驅動程序。但是,驅動程序返回任何錯誤的非常通用的錯誤消息。儘管現在我的原型在我認爲任何錯誤都是關鍵違規時都運行良好,但這種模式顯然存在很多缺陷。我找不到任何其他像樣的驅動程序/從erlang連接到mysql的方式。

由於Erlang和Mnesia無縫融合,我正在考慮切換到Mnesia(僅限內存模式以滿足我的速度要求)。但是,我發現Mnesia沒有任何可用於在單個查詢中執行數據庫更新的唯一鍵約束。

我需要關於如何最好地從Erlang內部實現這個需求的建議。有什麼方法可以在Mnesia中執行條件更新?或者,我還有其他高速數據庫選擇嗎?任何幫助/見解非常感謝。

回答

1

我不知道什麼是最好的解決方案,但我會嘗試做兩個表格一個記錄和一個索引與unique_constraint_field和處理每個CUD CRUD操作在交易檢查和更新索引。原因是在mnesia你不能設置索引類型,並且總是重複包。我認爲這是因爲你的指數無論如何都是唯一的,它不應該引入額外的表現懲罰。如果您使用mnesia索引功能,您仍然必須編寫自己的CUD操作,並且結果與使用兩個表格幾乎相同。幸運的是,mnesia以最少的開發工作量處理嵌套事務,與傳統的RDBMS相比,這件事相對容易。

1

Ulf Wiger發佈了一個庫,允許您使用mnesia作爲關係數據庫。它被稱爲'rdbms',它已經有幾年了,並且很久沒有更新過了,但你可以直接使用它,或者至少將自己的工作放在他的工作上來處理它。 Grab the source如果你想。

他的描述:

我重溫我的標準應答 的「RDBMS」的contrib提供了一個解決方案 此,通過提供支持 化合物的屬性和用戶定義 索引,包括選項 指定索引值必須爲 唯一。

Rdbms /已被商業使用, ,但我不認爲它準備好 商業用途。我沒有 做了很長一段時間的任何事情, ,因爲我不覺得任何用戶 壓力,但任何人想要這樣的變化,當然是歡迎聯繫我 我爭辯他們的情況。

http://ulf.wiger.net/rdbms/doc/rdbms.html (該文檔留下很多有待改進,我 知道 - 見上文)。

的文檔mentionning的 '獨一無二' 的約束,可以發現here。有可能會有性能點擊; mnesia是爲了成爲一個關鍵價值的存儲。我不能完全記住,但是可能在檢查它們時定義「唯一」索引可能涉及全表遍歷。

總而言之,因爲它很舊,所以在運行時可能會遇到麻煩。請參閱trapexit thread about it。用它來研究它是如何完成的可能是一個更好的主意。

2

mnesia可以crash與大量的寫入,除非你tune it。但是您可以使用看起來像{ID, UniqueConstraint}的複雜主鍵,這可以使您的更新變得更簡單。還有一個名爲osmos的新erlang庫,用於在專門爲處理大量寫入而創建的磁盤ordered_set表中。

+0

謝謝,這聽起來很有趣,會看看。 – jeffreyveon 2009-07-28 16:36:48