質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Q&A

解決済

3回答

5470閲覧

MySQLに複数選択項目のデータを保存する際にビットフラグを利用するが項目数が64個以上存在する場合どうすれば良いか?

hojo

総合スコア195

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

0グッド

0クリップ

投稿2016/10/01 21:15

Webサービスを作成していて、ユーザに入力してもらったデータをデータベースに保存したいとします。

ユーザに入力してもらうデータの中には「あなたの興味のあるものにチェックしてください」というような複数選択可能な項目があり「テレビゲーム」「ファッション雑誌」「ハイキング」というような項目が64項目以上あるとします。

もし複数選択可能な項目数が64以下である場合、8バイトのBIG INT型などを利用して8x8=64の64ビットを利用することで一つの整数にチェックされた項目の全てのパターンを保存することが可能になります。

しかし、項目数が64項目以上ある場合にはBIG INTでは足りません。代わりにvarcharを利用したりbinaryを利用したりできるのかな?と思ったのですが、解決方法がいろいろ考えられるため、最もシンプルかつ手間のかからない方法としてどんな手法が考えられるか意見をいただきたいと思い質問いたしました。

よろしくお願いいたしますm(_ _)m

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

NOTEPAD

2016/10/06 23:50

回答ではなく質問なので、こちらに書きます。Bit の計算は Webサービスがするならば BIGINT だろうと BINARY だろうと手間は変わらなくないですか?
hojo

2016/10/14 23:44

どういうことでしょうか?
guest

回答3

0

オーソドックスな形ということなら、以下のようになると思います。

sql

1CREATE TABLE `Users` ( 2 `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 3 `name` varchar(64) DEFAULT NULL, 4 PRIMARY KEY (`id`) 5) ENGINE=InnoDB DEFAULT CHARSET=utf8;

sql

1CREATE TABLE `Hobbies` ( 2 `id` int(11) unsigned NOT NULL AUTO_INCREMENT, 3 `name` varchar(64) DEFAULT NULL, 4 PRIMARY KEY (`id`) 5) ENGINE=InnoDB DEFAULT CHARSET=utf8;

sql

1CREATE TABLE `linkUserHobby` ( 2 `user_id` int(11) unsigned NOT NULL, 3 `hobby_id` int(11) unsigned NOT NULL, 4 PRIMARY KEY (`user_id`,`hobby_id`) 5) ENGINE=InnoDB DEFAULT CHARSET=utf8;

投稿2016/10/01 21:22

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ビットにした場合インデックスが効きませんから、「xxxに興味がある人」を抽出するのに、必ず対象テーブルをフルスキャンすることになるため得策ではありません。

投稿2016/10/06 03:10

kantomi

総合スコア295

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

アンケートをbit管理するのは賢明ではありません

  • 可変的ではない
  • 集計が煩雑になる
  • 選択肢が2択になる

やるなら設問idと設問番号、ユーザーid、回答カラムで更正された
テーブルを用意するとよいでしょう

設問ごとの上限を持ちたくない場合はピボットで処理すると楽です

投稿2016/10/02 05:27

yambejp

総合スコア114812

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hojo

2016/10/02 07:49

「可変的ではない」というのは、例えば3番目のビットにテレビゲームを割り当てた場合に、後から番号を変更したくなった時に変更しづらいということですか? また「選択肢が2択になる」というのはどういう意味でしょうか?
yambejp

2016/10/03 00:33

>後から番号を変更したくなった時に変更しづらい 概ねそういう意図です。 >「選択肢が2択になる」というのは 今回の命題ではチェックボックスですので問題なですが、 たとえばラジオボタンによる複数択一の場合も想定されます その際bit処理では0か1しか選べないため同じ構造が利用できないということです。
Panzer_vor

2016/10/03 13:11 編集

横槍失礼いたします。 手っ取り早さをとるなら確かに、 ・ビット文字列でフラグ管理をする が正解かもしれません。 ただし長期的に見ると、 ビット文字列での管理は得策じゃありません。 特にアンケート項目のように、 ①質問項目自体の意味が変わりうるもの ②質問項目数に増減があるもの 上記のような可変の特性を持ちうる情報は「列持ち・文字列持ち」から「行持ち」構造に変換するのが保守性・柔軟性が高いです。 (行持ちにすると桁数・カラム数などのしがらみから解放されますしね。) ビット文字列のデメリットして大きいのは、項目を増える分には精度を増やすだけですが、減らす際はフル桁利用した状態だとALTER時にエラーでこけます。 (末尾カットなどでデータを無理やり加工すれば定義変更はできるけど、やり方をミスるとデータの完全性が担保できなくなり危険。) yambejpさんが提示されているように、 対応する余裕があり、 かつアンケート内容が今後変わり得るなら、 ①ユーザマスタ ②アンケート項目マスタ ③アンケート回答テーブル の3つぐらいに分けるのが無難ですね。
hojo

2016/10/06 02:30 編集

ユーザテーブルを除き、一つの項目に対して2つのテーブルを用意するのが大袈裟なように感じているのですが、該当する項目に対応するテーブルをENUM型を利用したものを利用することで1項目1テーブルにする方法がこちら(http://stackoverflow.com/questions/18486218/how-to-implement-mysql-set-concept-with-over-64-members)に掲載されているように思えたのですが、こちらについてはどう思われますでしょうか?
Panzer_vor

2016/10/06 23:22

> hojoさん http://qiita.com/Inagawa/items/6e9745d2598aa713a1f3 提示されている手法は、MySQL実装依存となるため、 ・今後別のDBMSへの移行はない ・アンケート項目数に変更あるのは稀 上記であれば採用を検討しても良いかと思います。 ただ使う上では実装依存となることと、制約に柔軟性を持てないというデメリットを飲む必要はあります。 ちなみにSQLアンチパターンの「サーティワンフレーバー」という項に、 MySQLのenum型についての言及があるので、 興味があれば調べると良いです。 (リンク先でも触れてますが)
退会済みユーザー

退会済みユーザー

2016/10/06 23:27

ラジオなら 100 010 001 と選択項目数のビットを使えば規定数より増やせないな
hojo

2016/10/07 01:01

> Panzer_vor ありがとうございます!SQLアンチパターンを購入しましたのでこれから読んでみます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問