# 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](https://en.wikipedia.org/wiki/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](https://hexdocs.pm/no_noncense/NoNoncense.html#module-how-it-works) they have counter-like data locality, which helps your indexes perform well, [unlike UUIDv4s](https://www.cybertec-postgresql.com/en/unexpected-downsides-of-uuid-keys-in-postgresql/). 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](https://hex.pm/packages/once) and can be installed by adding `:once` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:once, "~> 0.0.6"}
]
end
```
## Docs
Documentation can be found on [hexdocs.pm](https://hexdocs.pm/once/).
## Usage
To get going, you need to set up a `NoNoncense` instance to generate the base unique values. Follow [its documentation](https://hexdocs.pm/no_noncense) to do so. `Once` expects an instance with its own module name by default, like so:
```elixir
# 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:
```elixir
schema "things" do
field :id, Once
end
```
And that's it! Be sure to look at [hexdocs.pm](https://hexdocs.pm/once/) for options and additional info.