2016-09-21 49 views
0

我現在有一個基本的用戶事件表中的下列表格佈局:對比唯一性的更好選擇?

CREATE TABLE IF NOT EXISTS events.events_by_user(
    user text, 
    added_week int, 
    added_timestamp timestamp, 
    event text, 
    uuid uuid, 
    PRIMARY KEY((user, added_week), added_timestamp, event, uuid)) 
WITH CLUSTERING ORDER BY(added_timestamp DESC) 

因此唯一性基本上由UUID作爲主鍵的最後一列中必要的。同一個用戶有幾次相同的事件有可能發生在同一個毫秒(時間戳)中。

另一種方法可能是(如果我沒有記錯的話),下降的uuid列由相對柱取代它,而不是像這樣:

CREATE TABLE IF NOT EXISTS events.events_by_user(
    user text, 
    added_week int, 
    added_timestamp timestamp, 
    event text, 
    frequency counter, 
    PRIMARY KEY((user, added_week), added_timestamp, event)) 
WITH CLUSTERING ORDER BY(added_timestamp DESC) 

我的想法是,我可以節省一些空間使用這個計數器,而且我的行不會變寬。我不確定,如果這可能會有其他性能影響維持這個櫃檯,或者如果有任何其他原因,爲什麼這可能不是一個好主意?

回答

1

爲什麼要使用一個計數器來節省空間? C *設計成語是使用空間來增益效率。

回到你的問題,專櫃幾乎都可以做什麼限制,如必須在其自己的表被用在你想要的主鍵,你可以有許多列,然後只計列。它們只支持遞增和遞減操作,並且由於它們只支持這兩個操作,所以每個查詢都不是冪等的。如果您可以忍受「計數」值的不準確性...(即使C * 2.1+緩解了這一點,過度計數也是衆所周知的問題)

這意味着您不能指定event列,因爲是不是你主鍵的一部分,所以你的設計是無效的。

回到你的獨特性要求,您可以使用timeuuid列類型。它們是基於時間的Type 1 UUID,並提供相當低的碰撞概率。從Cassandra wiki

類型1 UUID由以下部分組成:

  • 由100納秒間隔的計數的時間戳因爲 00:00:00.00,1582 10月15日(日格利高裏改革的基督徒日曆 )。

  • 甲版本(應該具有1的值)。

  • 的變體(其應具有2的值)。

  • 的序列號,它可以是一個計數器或一個僞隨機數。

  • 一個「節點」,它將成爲機器的MAC地址(它應該使UUID在整個機器上都是唯一的)。

與UUID的挑戰是,使之成爲 一臺機器上運行多個進程和多線程 在一個進程中運行是唯一的。上面指定的類型1 UUID也不是 。在具有多個內核的快速機器上,很有可能 具有以相同時間值生成的UUID。只有當順序號可以跨越線程和進程時,這個可以修復爲 ,這對於高效地執行相當具有挑戰性。

的時間參考的基於UUID通過補償這些問題:

  • 使用()由 System.currentTimeMillis的恢復正常毫秒的粒度和調整它假裝容納100張 納秒數只。

  • 每當遇到重複時間值時,將時間遞增1(以非線程安全方式) 。使用與序列號的UUID類關聯的僞隨機 號碼。 將時間增加1允許多個線程在同一個進程中在同一毫秒內唯一地創建多達10,000個UUID。使用 序列號的僞隨機數在每個UUID類將具有唯一ID的情況下提供1個16344個機會。

這些機制提供了合理的概率,即所生成的UUID將是唯一的。但是,要注意的問題是:

  • 計算機能夠每 微秒產生1點萬多的UUID。

  • 在不同線程上創建UUID的應用程序可能會得到重複,因爲時間不會以線程安全 的方式遞增。類的

  • 多個實例是在虛擬機中在不同的 類加載器 - 這將通過具有其自身的 序列號的每個類而減輕。

  • 不能保證相同或不同VM的UUID在 中的兩個實例將具有不同的序列號 - 只是 它們將具有合理的概率。

在實踐中,C *就已經做你想做的事。但是,如果您真的擔心自己最終會出現重複,那麼您需要自己進行適當的計數,並且建議您在應用程序級別實現這一點。

+0

我看到了,我用我的初始設計timeuuid,但有點害怕[this](http://nickberardi.com/sometimes-a-nanosecond-makes-all-the-difference/)文章。 Thx的努力,提到的概率是足夠好的,我會用timeuuid去。 – u6f6o