17
Quick Review of the Most Popular Ways to Implement Flags
There are many ways to store flags and use them for communication between
client <-> backend service
or service <-> service
. In the article, we are going to review the most popular options and we will try to help to choose the correct way for the next project.The most popular ways to work with flags are:
It means we would create a separate column in DB for each flag.
In an example,
| id | username | is_new |
|----|----------|--------|
| 1 | test1 | true |
| 2 | test2 | false |
is_new
will be a flag.| id | username | is_new |
|----|----------|--------|
| 1 | test1 | true |
| 2 | test2 | false |
In a code or a NoSQL database representation would be:
[
{
"id": 1,
"username": "test1",
"is_new": true
},
{
"id": 2,
"username": "test2",
"is_new": false
}
]
struct/class -> JSON -> protobuf -> MsgPack -> DB row -> struct/class
In my opinion, before using this approach, we should answer "yes" for all listed options in the checklist:
In the current implementation, we will store all flags as
strings
in an array.In a DB, we are going to store values in a separate table as one to many relationships.
Table
| id | username |
|----|----------|
| 1 | test1 |
| 2 | test2 |
user
:| id | username |
|----|----------|
| 1 | test1 |
| 2 | test2 |
Table
| id | user_id | flag |
|----|---------|---------|
| 1 | 1 | is_new |
| 2 | 1 | is_test |
user_flag
| id | user_id | flag |
|----|---------|---------|
| 1 | 1 | is_new |
| 2 | 1 | is_test |
Every
It can be optimized to not store the flag as a string, but in our current topic, it is not so important.
user_flag
row is linked to a row in user
table by user_id
field.It can be optimized to not store the flag as a string, but in our current topic, it is not so important.
In a code or a NoSQL database representation would be:
[
{
"id": 1,
"username": "test1",
"flags": [
"is_new",
"is_test"
]
},
{
"id": 2,
"username": "test2",
"flags": []
}
]
struct/class -> JSON -> protobuf -> MsgPack -> DB row -> struct/class
set
and unset
and find
functionsIn my opinion, before using this approach, we should answer "yes" for all listed options in the checklist:
To see code in action, simply read README.md from binflags library.
In DB we can store bitmask in various types, like:
| id | username | flags |
|----|----------|--------|
| 1 | test1 | 1 |
| 2 | test2 | 0 |
TINYINT
, SMALLINT
, MEDIUMINT
, INT
, BIGINT
, BLOB
types.| id | username | flags |
|----|----------|--------|
| 1 | test1 | 1 |
| 2 | test2 | 0 |
In the current example,
flags
field has the type INT
and the first bit is is_new
flag.In a code or a NoSQL database representation would be:
[
{
"id": 1,
"username": "test1",
"flags": 1
},
{
"id": 2,
"username": "test2",
"flags": 0
}
]
In my opinion, before using this approach, we should answer "yes" for all listed options in the checklist:
As we can see, as usual, we do not have silver bullet for all use cases and systems. But the provided list of implementations can help to find the best solution for a specific project.
If you want to use the most efficient option in Go, I would suggest checking Go implementation of binary flags for various types.
17