News for hackers. Stuff that matters.
Re:Cost of a Join by jaggederest on Tuesday August 14, 2018 @06:55PM (#17762620)
Enums add complexity that is better served by keeping the data relational, unless you have a really strong reason otherwise. If it was, for example, a statistical data table that was likely to have many billions of rows, I could see it, but then you're getting outside of the realm where you have truly relational data.
Re:Cost of a Join by barbegal on Tuesday August 14, 2018 @07:05PM (#17762674)
I would argue enums are less complex and easier to use. Imagine we were talking about a date field instead which is more complex?

A products table with a column called date (of type date)

Or a products table with a date_id column and a dates table with the columns date_id, date_year, date_month, date_day

Sure the second option may seem more relational but it is more complex. It allows you to do more relational things later if you want to attach things to a date like an is_holiday or a was_raining column.

So the question is, is there any value in adding the extra complexity now? If you foresee having to add more information to a status in a relational way like an is_active column then maybe a joined table is better.

Re:Cost of a Join by dragonwriter on Tuesday August 14, 2018 @07:15PM (#17762717)
> It allows you to do more relational things later if you want to attach things to a date like an is_holiday or a was_raining column.

While I get that calendar tables are fun and all, if you have a date type you can just add a “holidays” table for that if you need it later, without a table of all dates.

Re:Cost of a Join by jaggederest on Tuesday August 14, 2018 @07:43PM (#17762826)
Precisely. This is exactly why decomposing things into relations is important. The naive approach is to "keep all the things and all their details in one big table", and that's what causes so many problems.
Re:Cost of a Join by ryanmarsh on Tuesday August 14, 2018 @07:50PM (#17762857)
This thread is rehashing the trade offs of each form or “level” of normalization.

Various normal forms serve various purposes. Use what makes the most sense for your read and write demands.

Re:Cost of a Join by benjiweber on Wednesday August 15, 2018 @01:32AM (#17763957)
One big caveat with enums in postgres is that adding values can't be done in a transaction https://www.postgresql.org/docs/9.4/static/sql-altertype.htm...

It's modifying a type rather than values as it would be if we added a table, or schema if we added a column.

Re:Cost of a Join by patrec on Wednesday August 15, 2018 @02:53AM (#17764196)
It's annoying of course, but when is this a big problem in practice? I can imagine how it would be in theory, but in all cases where I needed to add an additional value to an enum so far, I could just do it independently of other schema changes and well in advance of deploying code that made use of the new value.
Re:Cost of a Join by jaggederest on Wednesday August 15, 2018 @03:03AM (#17764220)
Why do that when you can define it as a foreign key into a proper relation and modify it with full transactional guarantees? I just don't see the advantage of bending over backwards.

Remember, relations are "types" with existence checking built in and a whole powerful algebra around them. By dropping down to a more primitive type you gain very little and lose strong guarantees.

Re:Cost of a Join by patrec on Wednesday August 15, 2018 @04:04AM (#17764408)
Convenience. Having a table mapping id to string is logically equivalent and plays nicer with transactions. But it's much less convenient.

In principle SQL databases could have some sugar for foreign keys to tables that just bijectively map ids to human-readable identifiers, but they don't. I always wondered why not.

With enums I get readable, type-checked values I can auto-complete on and that I can use "in-place". With a table I don't get auto-completion and I need to do a join for readability if my enums are "true" enums (and have an ordering).

Re:Cost of a Join by jaggederest on Tuesday August 14, 2018 @07:48PM (#17762851)
An enum is a relation, it's just a relation that is not stored in the same kind of table that other data is.

Your example is really a fairly poor strawman. I would suggest something more like a product with a "release date" column, which would be decomposed into a "releases" table with a foreign key. That's the kind of decomposition I've done a lot, and it's usually a useful one.

Another example would be having an "address" field, versus having number, street, apartment/suite, city, state, zip, country. I generally go with address data in a separate, relational table, instead of inline (user_addresses vs on the user table directly), and I've found that to be very useful at times.

In a lot of cases, you actually want a separate table (keyed on the real value, of course, not a generated foreign key) that stores things like zip codes or countries, because there is a lot of ancillary data to associate with them.

If you value homoiconicity, you want all your data to be in as similar a format as possible. Enums are a special case, and so you should avoid them unless you have a strong reason otherwise.

Re:Cost of a Join by mamcx on Tuesday August 14, 2018 @09:20PM (#17763181)
> An enum is a relation

This is TRUE. Most people ignore the relational model despite being so simple to learn. But one important thing to note, is that similar how you can say "anything is a object" you can say "anything is a relation".

This is valid SQL:

    SELECT * FROM (SELECT 1) a
And because "1" is a relation, a enum is.

Normal rdbms fail at operate to inner values (like the array feature on postgresql) and don't allow to put tables into cells. This is valid at the relational level but you need to do hacky stuff for common rdbms.

    SELECT Head =(SELECT * FROM INVOICE)
I'm working in a relational language, and this will be valid:

    for i in 1 do
and

    select value:Some(1).... where value.isSome
Re:Cost of a Join by krychu on Wednesday August 15, 2018 @12:43PM (#17767447)
Enums are not relations but data types as indicated in the first paragraph here: https://www.postgresql.org/docs/current/static/datatype-enum..., and by the related command ‘CREATE TYPE ...’.

Relations are commonly used when referring to tables and views.

What do you gain by calling types relations while introducing confusion and diminishing practicality of the relation concept?

Re:Cost of a Join by dragonwriter on Wednesday August 15, 2018 @03:49PM (#17769117)
Finite data types are, or are isomorphic to, (constant) relations, they aren't relvars like tables/views (relations include both constant relations and relvars.)

> What do you gain by calling types relations

The fact that everything true of other relations is true of finite types.

Re:Cost of a Join by mamcx on Wednesday August 15, 2018 @03:08PM (#17768798)
That is true. In postgresql.

Not int the relational model.

Re:Cost of a Join by talaketu on Wednesday August 15, 2018 @12:41AM (#17763807)
I don't buy "enum is a relation" any more than "VARCHAR is a relation" or "REAL is a relation". These just data types that represent the domain or range of possible values that may participate in a relation.
Re:Cost of a Join by mbrameld on Wednesday August 15, 2018 @02:35AM (#17764131)
> that represent the domain or range of possible values that may participate in a relation

Like a foreign key constraint?

Re:Cost of a Join by CuriouslyC on Wednesday August 15, 2018 @10:05AM (#17766084)
Enums are much easier to deal with in application code, because you don't have to deal with joins and keep track of a separate entity. You could get the same effect using a string pkey, if performance isn't an issue. Enums are also ordered, which can be useful in certain circumstances.
Re:Cost of a Join by mmt on Wednesday August 15, 2018 @03:20PM (#17768895)
> Enums are also ordered, which can be useful in certain circumstances.

Are they ordered in a way that's different from an integer value that's a foreign key into another table?

The main difference I can perceive is that the ordering is non-obvious to a human, unlike integers, which seems less useful, not more.