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?

First Post!

idi527

idi527

:waving_hand:

I usually go with 1.

# migration
create table(:car_conditions, primary_key: false) do
  add :name, :string, primary_key: true
end

flush()

Repo.insert_all("car_conditions", [
  %{name: "new"},
  %{name: "excellent"},
  # ...
])

create table(:cars) do
  # ...
  add :contidion_name,
          references(:car_conditions,
            column: :name,
            type: :string,
            on_delete: :nilify_all,
            on_update: :update_all
          ),
          default: "good"
  # ...
end

# schema
schema "cars" do
  # ...
  field :condition_name, :string # or a custom ecto type like CarCondition
  # or field :condition, :string, source: :condition_name
  # or belongs_to if you have a schema for the condition type
  # ...
end

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

I think all approaches are more or less equivalent … I’ve found 1. a bit easier to manage than enums.

Most Liked

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.

Last Post!

OvermindDL1

OvermindDL1

Then I use an enumeration type, none of those 3 choices/options are required then.

Where Next?

Popular in Discussions Top

ben-pr-p
In general I’ve been sticking to this community style guide GitHub - christopheradams/elixir_style_guide: A community driven style guide ...
New
und0ck3d
Hello everyone! A few days ago I’ve created a topic here about how people were creating CMSs with Elixir and Phoenix. I’ve been studying...
New
PragTob
Hey everyone, this has been brewing in my head some time and it came up again while reading Adopting Elixir. GenServers, supervisors et...
New
AstonJ
If so I (and hopefully others!) might have some tips for you :slight_smile: But first, please say which area you’re finding most challen...
New
lucaong
Hello Elixir and Nerves community, I have been working for a while on an open-source embedded key-value database for Elixir, that I call...
230 14362 124
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
mmmrrr
Just saw that dhh announced https://hotwire.dev/ Is it just me or is this essentially live view? :smiley: Although I like the “iFrame-e...
New

Other popular topics Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54996 245
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New

We're in Beta

About us Mission Statement