alassek / activerecord-pg_enum

Integrate PostgreSQL's enumerated types with the Rails enum feature
MIT License
168 stars 10 forks source link

couple notes on readme #23

Closed jjb closed 3 years ago

jjb commented 3 years ago

Thanks for an awesome project! Couple notes on the readme:

If you choose the use varchar fields instead, now you have to write annoying check constraints and lose the efficient storage. enum status: { new: "new", active: "active", archived: "archived" }

You can actually continue to use integers in the db and do this:

enum status: { new: 0, active: 1, archived: 2 }`

Which solves the storage size and accidental reordering problems, but does not solve the ugly query problem.

An enum value only takes up four bytes.

You can actually back a rails enum with a 2-byte integer, with limit: 2 in the migration when creating the column.

I dream of a time when we can get the best of all worlds, where 1. postgres supports 1 or 2-byte columns, including for enums 2. rails supports postgres enums natively

alassek commented 3 years ago

The primary reason why I wanted to use string enums in the first place was the opacity of having integers in the SQL output, so yes while you can avoid one particular footgun with the enum helper by being more explicit, it doesn't solve the core problem.

I was only noting the size of the enum bytes to illustrate that you're not paying a significant cost by using them, I doubt the difference between four or two bytes would really matter to most people. It's noteworthy that enums are not integers in PostgreSQL because they use a floating point to support adding a new value in between existing ones.

jjb commented 3 years ago

The primary reason why I wanted to use string enums in the first place was the opacity of having integers in the SQL output

ahh, gotcha

It's noteworthy that enums are not integers in PostgreSQL because they use a floating point to support adding a new value in between existing ones.

I don't think that's true

https://www.postgresql.org/docs/13/datatype-enum.html#id-1.5.7.15.8

"Existing values cannot be removed from an enum type, nor can the sort ordering of such values be changed, short of dropping and re-creating the enum type. An enum value occupies four bytes on disk. "

alassek commented 3 years ago

I said adding a new value, not changing an existing one.

https://www.postgresql.org/docs/13/catalog-pg-enum.html

When an enum type is created, its members are assigned sort-order positions 1..n. But members added later might be given negative or fractional values of enumsortorder. The only requirement on these values is that they be correctly ordered and unique within each enum type.

This is how they support adding new values before or after existing values

jjb commented 3 years ago

Ah gotcha - I guess I need to grok this more. Thanks for the discussion!