• ベストアンサー

usersテーブルの構成カラムについて

MySQLバージョン4.1.16を使用しています。 このジャンルでお願いします。 よく全ての基本となるusersテーブル(IDとパスワードを入れるユーザの基本テーブル) があると思うのですが、それを構成するカラムはどのような感じにするのが良いのでしょうか? 自分は、 CREATE TABLE `users` ( `user_id` varchar(16), `password` varchar(255) default NULL, `col1` varchar(255) NOT NULL, `col2` varchar(255) NOT NULL, PRIMARY KEY (`user_id`), ) ENGINE=InnoDB; このように代替キー(連番)を使わずにuser_idを主キー(unique)にして構成します。 理由としては、uniqueな列があるなら、わざわざ連番を割り当てる必要もないし、 他のテーブルがuser_idを外部キーとして持った時に、その表の外部キーの列が 数字であるよりも見やすいかなと思ったからです。 ただ一般的に出まわっているPHPフレームワークなどのテーブル構成ではusersテーブルというか ほとんどのテーブルに連番を使っている例があります。 次のusersテーブルは、PHPフレームワークのCakePHPで使われるusersテーブルの構成の例で、 連番を使用しています。 CREATE TABLE `users` ( `id` int(11) NOT NULL auto_increment, `username` varchar(255) collate utf8_unicode_ci default NULL, `password` varchar(255) collate utf8_unicode_ci default NULL, `group_id` int(11) NOT NULL, `disabled` tinyint(1) NOT NULL, `created` datetime default NULL, `modified` datetime default NULL, PRIMARY KEY (`id`), KEY `group_id` (`group_id`), KEY `disabled` (`disabled`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 使用状況によって、どちらが良い悪いというのは変わるのでしょうけど 基本的にusersテーブルというのはどのような構成にすべきなのでしょうか? ちなみに自分は連番は○○_seqというカラム名にしてます(ただこれも 一般的には○○idを連番にしてるケースが多いので、どうすべきか迷っています・・・)

  • MySQL
  • 回答数3
  • ありがとう数3

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

代替キー(RDBMSにより、一意な連番を生成する機能を活用)は、部署コードなど「コード体系が変更される可能性が高い場合」に使うと便利な機能です。 従業員番号やユーザIDなど、一意でかつ「コード体系が変更される可能性が殆どない場合」には、あえて使う必要はありません。 操作ログを残していくようなテーブルでは、auto_incrementは便利ですね。auto_incrementの列だけ、あるいは(日時+auto_increment)で一意にして、時系列に操作を追跡できますから。

takagoo100
質問者

お礼

ご返答ありがとうございます。 お二方の意見で、自分の考えもまとまりました。ありがとうございます。 ところでこれは別の質問になっちゃうかもしれないのですが、 お答え頂けないでしょうか? int型(最小-2147483648, 最大2147483647)のauto_incrementの場合だと 21億以上は増やせないと思うのですが、これはbigint型(最小-9372036854775808, 最大9372036854775807) にした方がいいのでしょうか? まあ普通はそこまで行が増えるということはないのでしょうけど ログなどのテーブルで詰め込み方次第で21億以上増えないとは言い切れないですし、なんとなく気持ち悪いと思いまして・・・

その他の回答 (2)

回答No.3

>int型(最小-2147483648, 最大2147483647)のauto_incrementの場合だと >21億以上は増やせないと思うのですが、これはbigint型(最小-9372036854775808, >最大9372036854775807)にした方がいいのでしょうか? >まあ普通はそこまで行が増えるということはないのでしょうけど >ログなどのテーブルで詰め込み方次第で21億以上増えないとは言い切れない auto_incrementを使った場合、負の数は使われないのでUNSIGNED指定すれば、表現可能な最大値はさらに大きくなります。 InnoDBでは使えませんが、MyISAMなどでは、auto_incrementの列を、複合キーの2番目に指定することができます。 http://dev.mysql.com/doc/refman/4.1/ja/example-auto-increment.html 例えば、(日時,日時内通番)という構成で、日時毎に1からの通番を付けることも可能です。 商用RDBMSやPostgreSQLには、「シーケンス」という機能があります。MySQLのauto_incrementは、シーケンスに比べるとかなり簡易的な機能です。 現行システムの通番が上限に達する心配をしなければならない頃には、現行システムの見直しやMySQLの機能拡張が行われている可能性が高いと感じます。

takagoo100
質問者

お礼

ご返答ありがとうございます。 なるほど、複合キーというやり方は良さそうですね。 たしかにその頃にはシステムが変わってそうですね。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

>user_idを主キー 主キーは、削除、挿入、更新などにつかうためにユニークであり インデックスがはってあるキーですから、用途が微妙にことなります。 たとえば、場合によってはユーザーid自体なんらかの理由で変更 を迫られることもないとはいえません。 その際にユーザーidに依存しない独立したプライマリーキーを もっていれば、レコード自体を引き継ぐことができます。 そのリスクを理解しているのであればユーザーidにプライマリを設定 しても構わないでしょう。 ちなみに私はユーザーidをプライマリーキーにしてしまう派です。

takagoo100
質問者

お礼

ご返答ありがとうございます。 なるほど、変更する可能性も考える必要があるということですね。

関連するQ&A

  • mysqlのインデックスについて質問です。

    mysqlのインデックスについて質問です。 http://archiva.jp/web/server-side/sql_02.html に、 『mysqlでは1つのクエリ実行で、1つのテーブルにつき1つのインデックスしか使用できない』 とあります。 よく以下のようなテーブル定義を見かけますが、 CREATE TABLE IF NOT EXISTS `data` ( `id` int(10) NOT NULL default '0', `user_id` int(10) NOT NULL default '0', `file_id` int(10) NOT NULL default '0', `name` text collate utf8_unicode_ci NOT NULL default '', PRIMARY KEY (`id`), KEY `user_id` (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; idとuser_idを条件にするクエリであれば、上記制約を満たすため、 KEY `id_user_id_idx` (`id`,`user_id`) の複合クエリを定義すれば良いのでしょうか? また、idとuser_idとfile_idを条件にするクエリも考慮に入れた場合、 テーブル定義は以下のようにするのでしょうか? CREATE TABLE IF NOT EXISTS `data` ( `id` int(10) NOT NULL default '0', `user_id` int(10) NOT NULL default '0', `file_id` int(10) NOT NULL default '0', `name` text collate utf8_unicode_ci NOT NULL default '', PRIMARY KEY (`id`), KEY `user_id` (`user_id`), KEY `id_user_id_idx` (`id`,`user_id`), KEY `id_user_id_file_id_idx` (`id`,`user_id`,`file_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 最後に、create table 時のインデックスの指定は、 INDEX `user_id` (`user_id`), のようにもできますが、INDEXとKEYの違いは何かあるのでしょうか。

    • ベストアンサー
    • MySQL
  • tableをつくれない

    CREATE TABLE `db31_dev`.`db31_dev` ( `keyword_id` SERIAL NOT NULL , `bc_guid` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `bc_wbs` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `keyword_h1_url` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `keyword_wording_in_bc` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `keywords` VARCHAR( 511 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `description` VARCHAR( 255 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `last_modified` DATETIME NOT NULL , `changefreq` VARCHAR( 15 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `pri` INT( 5 ) NOT NULL , `noLocalNavi` BOOLEAN NOT NULL , PRIMARY KEY ( `keyword_id` ) , UNIQUE ( `bc_guid` , `bc_wbs` , `keyword_h1_url` , `keywords` , `description` ) ) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci; とphpmyadminでうったら(正確にはテキストボックスに入力) priの部分がエラーと言われて、 MySQLのメッセージ: ドキュメント #1071 - Specified key was too long; max key length is 767 bytes だそうです。 どうすればいいのでしょうか? よろしくお願い申し上げます。

    • ベストアンサー
    • MySQL
  • 同じ構成の2つのテーブルの更新について

    はじめまして、下のような2つの同じ構成のテーブルがあった場合に create table test1 ( key1 varchar(8) not null, key2 varchar(4) not null, key3 varchar(6) not null, key4 varchar(11) not null, suryo int(9), kingaku int(11), constraint test1_key primary key (key1,key2,key3,key4) ); create table test2 ( key1 varchar(8) not null, key2 varchar(4) not null, key3 varchar(6) not null, key4 varchar(11) not null, suryo int(9), kingaku int(11), constraint test2_key primary key (key1,key2,key3,key4) ); 10万件のtest1テーブルに 5件のtest2テーブルの内容をキー集計した結果を test1に反映するにはどうのようなSQL文を書けば、効率的なのでしょうか? 片方のテーブルはデータ量が多く、もう片方は数件の更新処理となります。 宜しくお願いいたします。 ・処理前 (test1テーブル) key1,key2,key3,key4,suryo,kingaku "20070521","1111","111111","11111111111",10,1000 "20070521","2222","222222","22222222222",5,5000 "20070521","3333","333333","33333333333",1, 100 (test2テーブル) key1,key2,key3,key4,suryo,kingaku "20070521","2222","222222","22222222222",10,30000 ↓ ・処理後 (test1テーブル) key1,key2,key3,key4,suryo,kingaku "20070521","1111","111111","11111111111",10,1000 "20070521","2222","222222","22222222222",15,35000 "20070521","3333","333333","33333333333",1, 100

    • ベストアンサー
    • MySQL
  • Data too long for column 'id' at row 1とエラー

    MySQLを3.27から2.0に変えたのですが、 Data too long for column 'id' at row 1 というエラーが表示されて困っています。 エラー 実行した SQL: ALTER TABLE `account` CHANGE `id` `id` VARCHAR( 3 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL , CHANGE `pass` `pass` VARCHAR( 3 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL , CHANGE `mail` `mail` VARCHAR( 16 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL , CHANGE `name` `name` VARCHAR( 6 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL , CHANGE `host` `host` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL MySQLのメッセージ: #1406 - Data too long for column 'id' at row 1 いきなりでどう対処していいか困っています。 どこを変更すればよいのでしょうか・・・?

  • 2つのテーブルからデータ取得

    いつもお世話になっております。 以下のようなテーブルがあります。 ---------- CREATE TABLE IF NOT EXISTS `students` ( `id` int(11) NOT NULL AUTO_INCREMENT, `student_number` bigint(20) DEFAULT NULL, `name` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ---------- CREATE TABLE IF NOT EXISTS `student_upload` ( `student_number` bigint(20) NOT NULL, `upload_id` int(11) NOT NULL ) ---------- データは以下のように登録されています。 students ---------- id|student_number|name 1 |11111     |いちろう 2 |22222     |じろう 3 |33333     |さぶろう student_upload ---------- student_number|upload_id 11111     |1 11111     |2 22222     |1 22222     |2 ---------- student_upload.upload_id=1 のデータを取得したいので 下記のようなSQL文を発行しているのですが、student_upload.upload_id=2 の データも取得されてしまいます。 select * from students s, student_upload up where up.upload_id=1 and up.student_number=s.student_number よろしくご教示お願いいたします。 <環境>  PHP:5.3.5  MySQL:5.0.7

    • ベストアンサー
    • MySQL
  • create時にFOREIGN KEYでエラー

    以下のSQL文を実行すると CREATE TABLE if not exists table_A ( id int(11) not null auto_increment, company_id int(11) not null, created_at datetime NOT NULL, updated_at timestamp NOT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; CREATE TABLE if not exists table_B ( id int(11) not null auto_increment, from_id int(11) not null, company_id int(11) not null, created_at datetime NOT NULL, updated_at timestamp NOT NULL, PRIMARY KEY (id) FOREIGN KEY (from_id) REFERENCES table_A(id) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; 上記を実行すると以下のエラーがでます。 #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FOREIGN KEY (from_id) REFERENCES table_A(id) ON DELETE CASCADE ) ENGINE=Inn' at line 8 解決方法をご存知の方はご教示頂けますと幸いです。 宜しくお願いいたします。

    • ベストアンサー
    • MySQL
  • カラム名でseqとidではどちらがふさわしいのでしょうか?

    mysql5.1.33を使用しています。 例えば、ユーザ情報を格納するuserテーブルがあって ユーザが決める半角英数字からなるIDを格納するuser_idカラムがあるとします。 そしてAuto Incrementなカラムも付け足すと、 [user] seq INT(11) NOT NULL AUTO_INCREMENT, user_id varchar(16) PRIMARY KEY (seq) UNIQUE KEY user_id (user_id) この場合はseqカラムが主キーになるわけですが、 一般的にはカラム名はseqではなくてidですよね? なんで自分はseqにしたかというと、 user_idカラムのidには文字(半角英字)のIDを、 seqは連番を意味づけさせたいと思いました。 つまり seqがつくカラム名は連番で idがつくカラム名は文字列 と直感的に分かりやすくなるだろうと思ったからなのですが、 みなさんはこのケース(そもそもこのカラム構成が正しいかは分かりませんが・・)の場合は、 どのようなカラム名を付けますか?

  • SQLにプログラムが反映されないのは何故

    XAMPP Version: 1.8.2 です。   Xamsのデータベースをデータベースから削除した後  SQLから、以下2個プログラムを入力しました。  すると、削除したにも関わらず、エラーが出て プログラムが反映されません。  Xamsを削除後、再起動したらまたXamsのデータベースが 再構築されます。  私は作成した記憶はありません。  すでに存在しているので、作成しする必要は ないのか、よくわかりません!?  皆様どう思われますか!?  以下入力したプログラムです。 ---------------------------------------------------------------- CREATE DATABASE xmas; USE xmas; CREATE TABLE xmastran ( book_id int not null auto_increment, name varchar(30) not null default '' , org varchar(50) not null default '', addr varchar(80) not null default'', tel varchar(20) default '', mail varchar(40) default '', course varchar(30) default '', nums integer default 0, PRIMARY KEY (book_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; エラー 実行したSQL: DATABASEクリスマスを作成します。 のMySQLのメッセージ:ドキュメント #1007 - データベース'クリスマス'を作成できません、データベースが存在している -------------------------------------------------- CREATE DATABASE if not exists xmas; USE xmas; CREATE TABLE xmastran ( book_id int not null auto_increment, name varchar(30) not null default '' , org varchar(50) not null default '', addr varchar(80) not null default'', tel varchar(20) default '', mail varchar(40) default '', course varchar(30) default '', nums integer default 0, PRIMARY KEY (book_id) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; エラー 実行したSQL: TABLE xmastranを(CREATE book_idのINT NOT NULL AUTO_INCREMENT、 名VARCHAR(30)NOT NULL DEFAULT''を、 orgのVARCHAR(50)NOT NULL DEFAULT''を、 addrはVARCHAR(80)NOT NULL DEFAULT''を、 電話VARCHAR(20)DEFAULT''を、 メールVARCHAR(40)DEFAULT''を、 もちろんVARCHAR(30)DEFAULT''を、 numsはINTEGERのデフォルトは0、 PRIMARY KEY(book_id) )ENGINE = MYISAM DEFAULT CHARSET= utf8を; のMySQLのメッセージ:ドキュメント #1050 - テーブル 'xmastran'は既に存在します。 ------------------------------------------------------------------- 以上よろしくお願いします。

    • ベストアンサー
    • MySQL
  • MySQLのテーブル設計で迷っています(桁数)

    MySQLのテーブル設計で迷っています。 クリエイト文のカッコの中は桁数を表しているのでしょうか?それともバイト数でしょうか?桁数であれば、それぞれの型で何桁まで設定できますでしょうか? int型のnoを18桁に変更したいのですが、調べているうちに迷ってしまいました。 型 バイト 最小値 最大値 TINYINT 1 -128 127 SMALLINT 2 -32768 32767 MEDIUMINT 3 -8388608 8388607 INT 4 -2147483648 2147483647 BIGINT 8 -9223372036854775808 9223372036854775807 CREATE TABLE `user` ( `no` int(8) unsigned NOT NULL auto_increment, `id` varchar(24) NOT NULL default '', `email` varchar(255) NOT NULL default '', `reg_date` datetime NOT NULL default '0000-00-00 00:00:00', PRIMARY KEY (`no`) ) TYPE=MyISAM;

    • ベストアンサー
    • MySQL
  • PHPの文字コードについて

    PHPとmysqlの文字コードの関係について 1.データベースは文字コード utf8_unicode_ci で作成しています。 2.以下のようにテーブルを作成しました。 CREATE TABLE `test` ( `qid` varchar(10) NOT NULL, `qtitle` varchar(255) default NULL, PRIMARY KEY (`qid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 3.show.phpの中で以下のように 出力しようとすると文字化けします。 show.phpファイルは文字コードutf8で保存しています。 <?php print($qTitle); ?> ブラウザの文字コードの設定はShift-Jisです。 ブラウザの文字コードを変えずに正しく表示させるためには どうすればいいのですか? ご教授よろしくおねがいします。

    • 締切済み
    • PHP