Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the maximum amount of flags flag_shih_tzu can handle?

I'm using "flag_shih_tzu" gem and I want to know what is maximum amount of flags that it can handle, or is it depend on the int. length in the flags column?
I need it to handle 64 flags.
can it?

like image 775
Nir Aviel Avatar asked Mar 23 '23 21:03

Nir Aviel


1 Answers

I am the maintainer of flag_shih_tzu.

Best Practice: Each column used for flags should have at most 16 flags set, for performance reasons. You will find that performance suffers too much with columns holding more than 16 flags.

Workaround: A single table can have multiple flag columns.

I would create a design as follows:


class Foo ...

  has_flags 1 => :is_a1,
            # ... snip ...
            16 => :is_a16,
            :column => 'flag_col_a'

  has_flags 1 => :is_b1,
            # ... snip ...
            16 => :is_b16,
            :column => 'flag_col_b'

  has_flags 1 => :is_c1,
            # ... snip ...
            16 => :is_c16,
            :column => 'flag_col_c'

  has_flags 1 => :is_d1,
            # ... snip ...
            16 => :is_d16,
            :column => 'flag_col_d'
end

Now when you have an instance of Foo:


foo = Foo.new
foo.is_d16 = false
foo.save

Now you can retrieve foo like this:


Foo.not_is_d16 # => [foo]

And if you want to also check other flags in the same query you should chain conditions together (in a bitwise optimized manner) as follows:


Foo.chained_flags_with(:not_is_d16, :is_d1, :is_d4, :not_is_d11, :is_d14) # => array of Foo objects matching the conditions

Now for the giant caveat! If you want to use the 4 columns together they will need to be in separate parts of the SQL WHERE clause, and thus in different active record relations.

Important Chained flags can only be chained with flags from the same column.


Foo.
  chained_flags_with(:not_is_a1, :is_a2).  # from flag_col_a
  chained_flags_with(:not_is_b3, :is_b4).  # from flag_col_b
  chained_flags_with(:not_is_c8, :is_c11). # from flag_col_c
  chained_flags_with(:not_is_d13, :is_d14) # from flag_col_d

Personally, I never go past 8 flags per column, and split my flags into as many columns as I need.

Recommendation: Combine flags for properties which will be queried together on the same column, to make best use of the bitwise arithmetic.

like image 164
Peter H. Boling Avatar answered Apr 06 '23 12:04

Peter H. Boling