seanmor5

seanmor5

Author of Genetic Algorithms in Elixir

Enum, Joins, or Strings

This is just a quick database design discussion. When you encounter a field in a database that can take on one of a set number of values, how do you handle storing them?

Let me give an example: A database that has a table for cars stores the condition the car is in. Say the options are: “New”, “Excellent”, “Good”, “Average”, and “Bad”.

The way I see it there are 3 options here in storing these conditions:

  1. Create a separate “condition” table with a relationship between that and the car table. This means you can associate more information with the condition.
  2. Store the condition in an enumerable type with the ecto enum library. Postgres handles the validation and such for you.
  3. Store the condition as a string and do all validation and such on the server side of things. This might be the simplest, but it’s a lot less flexible.

What do you all think is the best approach and why? Under what conditions would you choose one approach over another?

Most Liked Responses

al2o3cr

al2o3cr

Some questions that help me decide tables vs enums:

  • Does the code care about the values?

    • a type like “Car Condition” might only be used mostly for filtering / sorting. Code generally only interacts with values of this type in aggregate (“show a list of all conditions”) or from user input (“show cars with the car condition in params[:condition]”). Tables work great for this.

    • on the other hand, a type like “Order Status” that represents an order’s flow through a series of processes is used more specifically. Some code still uses values of this type for filtering and sorting, but code also refers to specific values of the type (“do X if the order status is new”). An enum makes a lot of sense here.

  • What does adding new values to the list mean?

    • Adding a new “Car Condition” value - “Shiny”, say - might not require any code changes at all
    • adding a new “Order Status” is likely to require code changes to do anything meaningful
  • What values need to be available during tests?

    • Tests might only need a non-empty set of available “Car Conditions”
    • Code will not work without a full set of “Order Statuses”

As with everything, there’s a lot of fuzziness - for instance, what if there’s a need to calculate an “average” car condition?

Approach 3 can be useful for short periods - for instance, if you’re prototyping a system and discovering which values should exist. Long-term, it can be hazardous to legacy data integrity.

Other approaches worth considering:

  • map the values to an integer for storage; this requires some discipline to not reuse values long-term. If you pick the right order - “New” => 5, “Excellent” => 4, etc in the car example - things like “average condition” are readily computable. Making an Ecto type should wrap that up neatly.

  • in the enum case, consider a table of “extra data” with a primary key of the enum type - that would allow using a standard belongs_to to fetch the “extra data” for a record

cnck1387

cnck1387

Depends a lot on the use case. For things that will very likely not change enums are useful.

For example if you have a discount schema and one of the fields is value_type which can either be fixed or percent then an enum fits here very well. The ecto enum lib is quite nice for this because you can reference your values as :fixed or :percent in the code base, so it retains readability.

Where Next?

Popular in Discussions Top

matthias_toepp
I’d love to hear what people think about Wisp, the new Gleam web framework started by Gleam’s primary creator Louis Pilfold. Gleam, alon...
New
pillaiindu
In django there is a cache framework backed by memcached. Rails also puts a lot of emphasis on caching, and even the idea of russian-doll...
New
axelson
Decided against including more info in the title, but the gist is that Plataformatec sponsored projects will continue with the assets bei...
New
WildYorkies
It seems that the more I read, the more I find Elixir users speaking about all the ways that Elixir is not good for x, y, and z use cases...
New
nunobernardes99
Hi there Elixir friends :vulcan_salute: In a recent task I was on, I needed to check in two dates which of them is the maximum and which...
New
Ankhers
Just a little information upfront. Generally speaking, if I feel like I need to either break a pipe chain or use an anonymous function in...
New
rower687
Hi all, I’ve been reading a lot about the “let it crash” term and how supervising processes and the whole messaging passing make an elixi...
New
shishini
I think this twitter post and youtube video didn’t get as much attention as I hoped I am still new to Elixir, so can’t really judge ...
New
griffinbyatt
Sobelow Sobelow is a security-focused static analysis tool for the Phoenix framework. For security researchers, it is a useful tool for g...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New

Other popular topics Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement