MySQLであるテーブルにフラグのカラムを複数追加しようと思いました。
型はBOOLEANです。
例として以下のようなカラムのテーブルだとします。
ID, flag1, flag2, flag3, flag4, flag5, flag6
CREATE TABLE tb ( ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, flag1 BOOLEAN, flag2 BOOLEAN, flag3 BOOLEAN, flag4 BOOLEAN, flag5 BOOLEAN, flag6 BOOLEAN, ) ENGINE=InnoDB CHARSET=utf8;
しかし上記のようにフラグだけの列がいくつもというのはどうなのかと思います。
そこでどのような方法がよいのでしょうか?
- 正規化してそもそもtrueとなる行だけ存在するようにする
- 上記のようにそれぞれおフラグのカラムを持つ
- ビットフラグを使う
個人的に3のビットフラグに興味があるのですが、なかなか理解するのが難しいです。
何かアドバイスをいただけたらと思います。
どうぞよろしくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
ベストアンサー
本題とはそれますが、どんな物かということであれば
参考ページ ビット演算 ビットフラグ
flag1 = 1 //00000001
flag2 = 2 //00000010
flag3 = 4 //00000100
flag4 = 8 //00001000
flag5 = 16 //00010000
flag6 = 32 //00100000
のように決めておいて、
・記録時はflag2とflag6がonのレコードには2+8の10を記録します //00001010
・flag4がonのレコードを得たければ、8とのビットANDを行って0で無いか調べます
SQL
1select * from tb where (flags & 8) > 0 2
・flag1とflag6の両方がonのレコードを得たければ合計値とビットANDを行って同じかを調べます
SQL
1select * from tb where (flags & (1+32)) = 33 2
・flag1かflag6の片方がonのレコードを得たければ合計値とビットANDを行って0で無いか調べます
SQL
1select * from tb where (flags & (1+32)) > 0 2
・flag1,flag2,flag4がonで他は全てoffのレコードを得たければ合計値と一致するかを調べます
SQL
1select * from tb where flags = 11 2
ビットANDは演算する両値で共にonのビットのみをonにし他は全てoffにするため、これらような事が可能です。
###長所:
・複数flagのANDやORの比較が一度に行える
・フラグ記録セルが少なくて済む
###短所:
・どの数字がどのフラグか一目でわからない。
・データを見ても何がonで何がoffかを把握するのが大変
・何本までが有効なフラグで、それぞれどのような意味かDBを覗いてもわからない
・設計書も工夫しないとどのフラグが何の意味なのかわからなくなる。
・コードの可読性が低い
※コード上だけでフラグの意味や値を変更して、設計書の編集を放置したりしたら目もあてられません。
※(flags & 51)この比較はどのフラグについて調べているのかぱっと分かりません。
※※定数化しておいて(flags & flag1+flag2+flag4+flag5)のように使うのですが……
※またビットフラグを使用したシステムと把握していないと、いきなりコードだけ見ても何をしているのかわかり難いです。
###その他
・int4で管理すると31本まで(32?)のように1セルで管理できるflag数に限界があり増やしたくなると困る。
・データ量はboolのflagが6本なら6bit(?)だが、int4が一つで32bit。
※ただし管理ビットなどを考慮すると結果的にbitflagの方が少ない気がします。
※ただいずれにしても微差ですね。
###最後に
実際混乱するだけなので推奨しません。
よほど多数のフラグを扱うなら便利ですが、まずはそのシステム設計を見直すべきです。
ゲームプログラムでキャラの状況把握に使われる事があるみたいです。
投稿2015/08/01 20:43
総合スコア2068
0
全部で7フィールド程度ならこのままでいいと思います。最適化はもちろん大切ですが、デバッグのしやすさや拡張性、メンテナンス性も考慮した方がいいかと思います。
投稿2015/08/01 13:16
総合スコア1151
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2015/08/01 16:21
退会済みユーザー
2015/08/02 00:48 編集
2015/08/02 01:24
退会済みユーザー
2015/08/02 01:36
2015/08/03 00:07
0
教科書的には、フラグ用のテーブル用意したほうがよい気がします。
これだけ並ぶとフラグの増減がある気がするからです。
欠点としては、検索時に負荷がかかることが心配されます。
IOのオーバーヘッドは、送受信するデータ量の方が検索の時間より影響が
大きいので、どっちも注意が必要ですけど。
フラグ用のテーブルは”外部キー+フラグ種別”でPrimaryKeyとして、項目としてはフラグが入ります。
また、使わなくなったフラグを名称変更せずに使うと意味がカラム名から
わからなくなったりするので、気をつけたほうが良いです。
ビットテーブルも有効ですが、やはり、意味がわからなくなりやすいので
管理方法はきっちり考えたほうが良いとおもます。
投稿2015/08/02 01:24
総合スコア2883
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/08/04 09:24
0
こんばんわ。
用途がチェックボックス的な役割ならば、私は日付(日時)を持たせます。
trueにした日付(日時)を記録し、falseならNULLにします。
こうすることにより、trueにした日付(日時)を記録することもできます。
結局、用途がわからないので、これもおすすめできるかどうかは分かりません…。
投稿2015/08/01 15:19
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/08/02 00:41
0
ビットフラグのみの回答で該当かどうかわかりませんが、昔あるメーカーの商品製造工程でビットフラグを使った事があります。
ある商品を作るために複数の材料を投入するのですが、材料もほとんどが複数の商品に使われる物だった為
製品に使う材料に1~52(材料が52個あった)まで番号を付け、製品の方には使う材料の該当ビットをONしたデータを持たせました。で、投入可かどうかの判定に部品の番号に対応したビットがONならば投入できるという判断をしました。・・・そういう使い方ならビット判断でいいと思います。
逆に別々の判断をする為のフラグであればお勧めしません。
投稿2015/08/01 13:54
総合スコア6851
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/08/01 14:50
2015/08/01 22:24 編集
0
テーブル構造だけ見せられても判断はできませんね…
どういうシステムでそのフラグがどういう意味を持っているのか、がわからないとそれが妥当なのかどうかは判断できません。
投稿2015/08/01 13:16
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/08/01 14:54 編集
退会済みユーザー
2015/08/01 15:21
退会済みユーザー
2015/08/01 15:27
0
一つのアイデアを述べます。(これがベストかは、状況によります)
- 1 つのカラムだけを追加する。
- データ・タイプは String とする。
checkbox の on は 1, off は 0 として 文字列 "010101" のようにして 6 つの bool 値を6文字で表す事にする。 - この列には index を張る。
select で文字列 "010101" のような文字列を指定したり、like で正規表現を指定したりして検索を行うようにします。
投稿2015/08/02 16:37
総合スコア22324
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/08/04 09:31
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/08/02 00:46
2015/08/02 01:07 編集
2015/08/02 01:14
退会済みユーザー
2015/08/04 09:25