Skip to content
/ Once Public

An Ecto type for locally unique 64-bits IDs generated by multiple Elixir nodes

License

Notifications You must be signed in to change notification settings

juulSme/Once

Repository files navigation

Once

Once is an Ecto type for locally unique 64-bits IDs generated by multiple Elixir nodes. Locally unique IDs make it easier to keep things separated, simplify caching and simplify inserting related things (because you don't have to wait for the database to return the ID). A Once can be generated in multiple ways:

  • counter (default): really fast to generate, predictable, works well with b-tree indexes
  • encrypted: unique and unpredictable, like a UUIDv4
  • sortable: time-sortable like a Snowflake ID

A Once can look however you want, and can be stored in multiple ways as well. By default, in Elixir it's a url64-encoded 11-char string, and in the database it's a signed bigint. By using the :ex_format and :db_format options, you can choose both the Elixir and storage format out of t:format/0. You can pick any combination and use to_format/2 to transform them as you wish!

Because a Once fits into an SQL bigint, they use little space and keep indexes small and fast. Because of their structure they have counter-like data locality, which helps your indexes perform well, unlike UUIDv4s. If you don't care about that and want unpredictable IDs, you can use encrypted IDs that seem random and are still unique.

The actual values are generated by NoNoncense, which performs incredibly well, hitting rates of tens of millions of nonces per second, and it also helps you to safeguard the uniqueness guarantees.

The library has only Ecto and its sibling NoNoncense as dependencies.

Installation

The package is hosted on hex.pm and can be installed by adding :once to your list of dependencies in mix.exs:

def deps do
  [
    {:once, "~> 0.0.1"}
  ]
end

Docs

Documentation can be found on hexdocs.pm.

Usage

To get going, you need to set up a NoNoncense instance to generate the base unique values. Follow its documentation to do so. Once expects an instance with its own module name by default, like so:

# application.ex (read the NoNoncense docs!)
machine_id = NoNoncense.MachineId.id!(opts)
NoNoncense.init(name: Once, machine_id: machine_id)

In your Ecto schemas, you can then use the type:

schema "things" do
  field :id, Once
end

And that's it! Be sure to look at hexdocs.pm for options and additional info.

About

An Ecto type for locally unique 64-bits IDs generated by multiple Elixir nodes

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages