プライマリーキーの昇順でソートにならないのは?

このQ&Aのポイント
  • PHPで開発中のテーブルが、プライマリーキーの昇順でソートされない問題について質問します。
  • 提供されたテーブルの構造を確認し、指定のクエリがIDの昇順になってくれない理由についても詳しく解説します。
  • また、提案として、order byを使用する以外に解決策があるのかについても調査し、ご助言します。
回答を見る
  • ベストアンサー

プライマリーキーの昇順でソートにならないのは?

現在PHPで開発しています。 テーブル構造は下記の通りです。 CREATE TABLE `timetable` ( `ID` int(3) unsigned NOT NULL auto_increment, `gettime` int(10) unsigned default NULL, `code` varchar(20) default '0', //英数字が入る `time` varchar(50) default '0', //日本語が入る `timeh` datetime default NULL, PRIMARY KEY (`ID`), KEY `gettime` (`gettime`) ) ENGINE=MyISAM DEFAULT CHARSET=ujis これでふつうに select ID,gettime,code from timetable where code='xxx' とすると ------------ 16435 5 xxx 16434 4 xxx 16433 3 xxx 16432 2 xxx 16431 1 xxx と取得されてしまい、IDの昇順になってくれません。 select * でも同様です。LIFO型になっているように見られます。 ご助言いただきたいのは ・MySQLの場合、こうなることはあるのか、原因は何か ・対応としてはorder by をつける以外にないのか  (テーブルの構造、設定を変えることで対応可能か) です。お忙しいと存じますが宜しくお願い致します。

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

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

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

殆どのRDBMSでは、以下を保証していません。 (1)「order by」指定なしでのプライマリキー順などの順序保証 (2)「order by」指定なしでの格納順などの順序保証 MySQLでも、「order by」指定なしで、「プライマリキー順になったり、格納順になったり」といったことは、一切保証されていません。 マニュアルにも「order by指定がない場合は、順序保証しない」ことは明記されています。 また、「明記されていないが、実は格納順になるのでは?」というのを実験して、「確実には格納順にならない」という実験結果を公開しているサイトもあります。 例外的にSQL Serverでは、「order by指定なし」でプライマリキー順を保証しているようですが、これは例外中の例外と言えます。

deck_hiromi
質問者

お礼

ありがとうございました!

その他の回答 (2)

  • calltella
  • ベストアンサー率49% (317/635)
回答No.2

逆でしたか・・・失礼しました。 ですが、結果は同じです。 後から追加したのが最新なので上になります。

  • calltella
  • ベストアンサー率49% (317/635)
回答No.1

------------ 16435 5 xxx 16434 4 xxx 16433 3 xxx 16432 2 xxx 16431 1 xxx (16431~16435)までが時間で(1~5)までがIDですよね? 後から追加したのが最新なので上に来るのではないですか? 降順にするのにはorder by をつけるしかないでしょうね。

deck_hiromi
質問者

補足

>(16431~16435)までが時間で(1~5)までがIDですよね? いえ、違います。逆です。IDが5ケタの数値のほうです。

関連するQ&A

  • テーブルに空文字を入力させない方法

    MYSQLで下記のようなテーブルがあります。codeが主キーになっています。 +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | day | varchar(255) | YES | | NULL | | | time_mm | varchar(255) | YES | | NULL | | | time_ss | varchar(255) | YES | | NULL | | | id | varchar(255) | YES | | NULL | | | code | varchar(255) | NO | PRI | NULL | | | stock | varchar(255) | YES | | NULL | | +---------+--------------+------+-----+---------+-------+ selectでデータを引っ張ってくると下記のようになります。 +------+---------+---------+-------+------+-------+ | day | time_mm | time_ss | id | code | stock | +------+---------+---------+-------+------+-------+ | NULL | NULL | NULL | dd | | NULL | | 1111 | 2222 | 3333 | 4444 | 1234 | 6666 | | 11 | 22 | 33 | 44 | 4649 | 66 | | 111 | 222 | 333 | 444 | 5963 | 666 | | NULL | NULL | fdfd | fdfd | fd | NULL | +------+---------+---------+-------+------+-------+ codeの一番上が空文字列になっているので、テーブルにデータが入っていると思うのですが、空文字も入力不可にさせたいです。 どのようにすれば実現させることができるでしょうか?

  • 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
  • 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
  • auto_incrementを任意の数字から開始するには

    次のようなテーブルで入力するとidが1~始まりますが、 これを1000~開始する方法が分かりません、ご教授お願いします。 CREATE TABLE addressbook ( id smallint(4) UNSIGNED NOT NULL auto_increment, name1 varchar(20) default NULL, birthday date default NULL, PRIMARY KEY (id) ) ENGINE=MyISAM DEFAULT CHARSET=sjis;

    • ベストアンサー
    • MySQL
  • SQLのSELECT文について

    以下の注文テーブルで、注文件数と送料と注文合計金額を一度に取得する場合、以下のようなSQL文で合っていますか? "SELECT order.total, order.delivery_fee, SUM(order.total * order.tax) AS total_for_paying FROM order"; CREATE TABLE `order` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, `status` tinyint(3) UNSIGNED NOT NULL DEFAULT '0', `order_payment_status` tinyint(3) UNSIGNED NOT NULL DEFAULT '0', `buyer_id` bigint(20) UNSIGNED NOT NULL, `discount` INT(11) UNSIGNED NOT NULL, `delivery_fee` INT(11) UNSIGNED NOT NULL, `charge` INT(11) UNSIGNED NOT NULL, `total` INT(11) UNSIGNED NOT NULL, `tax` INT(11) UNSIGNED NOT NULL, `total_with_tax` INT(11) UNSIGNED NOT NULL, `total_for_paying` INT(11) UNSIGNED NOT NULL, `use_point` INT(11) UNSIGNED NOT NULL, `created` DATETIME NOT NULL, `updated` DATETIME NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

    • ベストアンサー
    • MySQL
  • selectで特定の列をwhereで指定するとエラーになる

    今MYSQLのselect文でエラーが出ていて、where でgroupを指定するとエラーが出ます。どこかの書き方が間違っているようなのですが、正しい書式を教えていただけないでしょうか? 色々と実験してみて同じ書き方でほかの列を検索したときは検索が出来ることがわかったので、どこを直していいのかわからない状態です。 環境はWinXP Home SP2 MySQL 5.0.27-community-nt です。 操作しているテーブルは以下の通りで、IDやscodeを検索しようとすると正常に表示されます。 CREATE TABLE `product` ( `ID` int(11) default NULL, `id_seq` int(11) default NULL, `scode` varchar(50) default NULL, `rec_ctl` varchar(10) default NULL, `dir` varchar(100) default NULL, `image` varchar(100) default NULL, `image_s` varchar(100) default NULL, `brand` varchar(100) default NULL, `goods` varchar(100) default NULL, `group` varchar(50) default NULL ); 実行したSQL文と結果です。 mysql> select * from product where group = 'a'; ERROR 1064 (42000): 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 'group = 'a'' at line 1 IDなどであれば検索が出来ます。 mysql> select * from product where id = 'a'; Empty set (0.00 sec) それではよろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • 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 SELECTの指定について

    まず、御覧頂きありがとうございます。 早速質問なのですが、 CREATE TABLE `hoge` ( `id` int(8) NOT NULL, `name` varchar(30) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `hoge` (`id`, `name`) VALUES (1, 'hogeA'), (2, 'hogeB'), (3, 'hogeC'), (4, 'hogeD'); CREATE TABLE `test` ( `id` int(8) NOT NULL, `name` varchar(30) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `test` (`id`, `name`) VALUES (1, 'testA'), (4, 'testD'); という値が入ってるテーブルがあるとします。(長くなってすみません) で、 hoge.id と test.id が重複した場合 test.name を表示させたいです。 期待値としては id,name 1.testA 2,hogeB 3,hogeC 4,testD になります。 業務でJoinを使うようなテーブル構造にそもそもしないというのもあり、クリティカルなSQLコードに不慣れで御知恵を借りたく質問させて頂きました。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • text型とuniqueについて

    mysqlでテーブル作成したいのですが l_urlのtext型のuniqueは、どうやって作成したらいいのでしょうか? 後、テーブル作成を実際すると結構つまずくので練習したいのですが 何かいい勉強方法はありますか? /* リンクデータ用テーブル作成 CREATE TABLE linkdata ( id int NOT NULL auto_increment, l_url text NOT NULL unique, l_title varchar(100) NOT NULL default '', l_comment varchar(255) default NULL, l_date datetime default NULL, PRIMARY KEY (id) ); 実行結果: ERROR 1170 (42000): BLOB/TEXT column 'l_url' used in key specification without a key length mysql>

    • ベストアンサー
    • MySQL
  • perlのプログラムでエラーが出ます。

    普段PHPerなんですがbatchの関係でperlを使用しなければならなくなり書いていたんですが、 下記のソースコードの中でINSERT INTOの部分でエラーが発生してしまいます。 最初selectしている部分はcreate tableで作っているテーブル構成と同じです。 それからサイト名に関するレコード部分は*で隠しています。 よろしくお願いいたします。 #!/usr/bin/perl use DBI; # データソース $d = 'DBI:mysql:a_anime'; # ユーザ名 $u = '************'; # パスワード $p = '************'; # データベースへ接続 $dbh = DBI->connect($d, $u, $p); $sth = $dbh->prepare("select * from tweet where tweetid BETWEEN '1' AND '21562745' limit 5"); $sth->execute; while( @row = $sth->fetchrow_array ){ $priduct_id = @row['3']; $user_url = @row['6']; $sth2 = $dbh->prepare("show tables from a_anime like 'tweet_@row['3']'"); $sth2->execute; @row2 = $sth2->rows; $sth2->finish; if (@row2 != 1){ $sth22 = $dbh->prepare("CREATE TABLE `tweet_@row['3']` ( `id` int(255) NOT NULL auto_increment, `userid` int(25) DEFAULT NULL, `text` text NOT NULL, `product_id` int(255) NOT NULL, `product_name` varchar(30) NOT NULL, `date` varchar(20) NOT NULL, `user_url` varchar(160) NOT NULL, `username` varchar(100) NOT NULL, `flag` int(1) NOT NULL DEFAULT '1', `rev_point` int(1) NOT NULL DEFAULT '1', `t_tweetid` bigint(255) DEFAULT NULL, `rev_id` int(10) DEFAULT NULL, `rev_flag` int(1) NOT NULL DEFAULT '0', `*****_flag` int(1) DEFAULT NULL, `res_info` int(100) DEFAULT NULL, `fav_info` int(255) DEFAULT NULL, `user_img` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`), KEY `index3` (`flag`), KEY `user url` (`user_url`), KEY `t_tweetid` (`t_tweetid`), KEY `index4` (`flag`,`rev_point`,`product_id`), KEY `index5` (`flag`,`product_id`), KEY `index6` (`userid`,`flag`), KEY `index7` (`username`,`flag`), FULLTEXT KEY `index2` (`text`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8"); $sth22->execute; $sth22->finish; } $sth3 = $dbh->prepare("select user_url from tweet_@row['3']"); $sth3->execute; print "@row['3']\n"; print "@row['6']\n"; @row3 = $sth3->fetchrow_array; $sth3->finish; #if ($user_url != $row3){ print @row['2'] ; print "\n"; $sth4 = $dbh->prepare("INSERT INTO tweet_@row['3'] VALUES (@row['1'],@row['2'],@row['3'],@row['4'],@row['5'],@row['6'],@row['7'],@row['8'],@row['9'],@row['10'],@row['11'],@row['12'],@row['13'],@row['14'],@row['15'],@row['16'])"); print $sth4; print "\n"; $sth4->execute; $sth4->finish; } } $sth->finish; $dbh->disconnect;