1. 問題の説明 root@mysqldb 22:12: [xucl]> テーブル t1\G の作成を表示します ************************** 1. 行 **************************** 表: t1 テーブルの作成: CREATE TABLE `t1` ( `id` varchar(255) デフォルト NULL ) エンジン=InnoDB デフォルト文字セット=utf8 セット内の 1 行 (0.00 秒) root@mysqldb 22:19: [xucl]> t1 から * を選択します。 +--------------------+ |id| +--------------------+ | 204027026112927605 | | 204027026112927603 | | 2040270261129276 | | 2040270261129275 | | 100 | | 101 | +--------------------+ セット内の 6 行 (0.00 秒) 奇妙な現象: root@mysqldb 22:19: [xucl]> id=204027026112927603 の t1 から * を選択します。 +--------------------+ |id| +--------------------+ | 204027026112927605 | | 204027026112927603 | +--------------------+ セット内の 2 行 (0.00 秒) 640?wx_fmt=jpeg 一体全体、204027026112927603 を確認したのに、なぜ 204027026112927605 も出てきたのでしょうか? 2. ソースコードの説明 コールスタックの関係は次のとおりです。 JOIN::exec()は実行エントリポイントであり、Arg_comparator::compare_real()は等価判定関数であり、以下のように定義される。 int Arg_comparator::compare_real() { /* Bug#2338のもう一つの症状を修正。「Volatile」は次のように指示します。 gccは80ビットIntel FPUレジスタからdouble値をフラッシュする前に 比較を実行します。 */ 揮発性ダブル val1、val2; val1 = (*a)->val_real(); if (!(*a)->null_value) { val2 = (*b)->val_real(); if (!(*b)->null_value) { (set_null)の場合 所有者->null_value = 0; val1 < val2 の場合は -1 を返します。 val1 == val2 の場合は 0 を返します。 1 を返します。 } } (set_null)の場合 所有者->null_value = 1; -1 を返します。 } 比較手順を下図に示します。t1 テーブルの id 列が行ごとに読み取られ、val1 に格納されます。定数 204027026112927603 がキャッシュに存在し、その型は double (2.0402702611292762E+17) です。したがって、値が val2 に渡された後、val2=2.0402702611292762E+17 になります。 1行目までスキャンすると、204027026112927605をdouleに変換すると2.0402702611292762e17となり、等式が成立し、適格行であると判定され、スキャンが続行されます。同様に、204027026112927603も条件を満たしています。 文字列型数値から倍精度型数値への変換がオーバーフローするかどうかを検出するにはどうすればよいでしょうか。ここでテストしたところ、数値が16桁を超えると、倍精度型への変換は正確ではなくなりました。たとえば、20402702611292711は、20402702611292712と表現されます(図のval1に示すように) MySQL 文字列を double に変換するための定義関数は次のとおりです。 { char buf[DTOA_BUFF_SIZE]; ダブル解像度; DBUG_ASSERT(end != NULL && ((str != NULL && *end != NULL) || (str == NULL && *end == NULL)) && エラー != NULL); res = my_strtod_int(str、end、error、buf、sizeof(buf)); 戻り値 (*error == 0) ? res : (res < 0 ? -DBL_MAX : DBL_MAX); } 実際の変換関数 my_strtod_int は dtoa.c にあります (複雑すぎるので、コメントを投稿してください) /* IEEE 算術マシン用の strtod。 このstrtodは入力された10進数に最も近い機械数を返します。 文字列(またはerrnoをEOVERFLOWに設定)。同点の場合はIEEEラウンドイーブンで決着する。 ルール。 ウィリアム・D・クリンガーの論文「浮動小数点数の読み方」に大まかに触発されて 「ポイント番号を正確に示す」[Proc. ACM SIGPLAN '90、pp. 92-101]。 変更点: 1. 必要なのは IEEE のみです (IEEE ダブル拡張ではありません)。 2. 浮動小数点演算で済むケース クリンガーは失敗しました -- d * 10^n を計算しているとき 小さな整数dと整数nが大きすぎる場合は 22(kが最大となる整数)よりはるかに大きい 10^kを正確に表現できる場合、 1回の丸めだけで (d*10^k) * 10^(ek) を計算します。 3. バイナリを少しずつ調整するのではなく その結果、難しいケースでは浮動小数点を使用する。 調整を決定するための算術 1ビット;本当に難しい場合にのみ、 2番目の残差を計算します。 4. 3. のため、10の累乗の大きな表は必要ありません。 10の倍数(例えば10^kの小さな表) (0 <= k <= 22)。 */ この場合、オーバーフローが発生しない場合をテストしてみましょう。 root@mysqldb 23:30: [xucl]> id=2040270261129276 の t1 から * を選択します。 +------------------+ |id| +------------------+ | 2040270261129276 | +------------------+ セット内の 1 行 (0.00 秒) root@mysqldb 23:30: [xucl]> id=101 の場合、t1 から * を選択します。 +------+ |id| +------+ | 101 | +------+ セット内の 1 行 (0.00 秒) 結果は予想通りであり、この場合、正しい書き方は次のようになります。 root@mysqldb 22:19: [xucl]> id='204027026112927603' の t1 から * を選択します。 +--------------------+ |id| +--------------------+ | 204027026112927603 | +--------------------+ セット内の1行(0.01秒) 結論 暗黙的な型変換は避けてください。暗黙的な変換には、主に、一貫性のないフィールド型、in パラメータ内の複数の型、一貫性のない文字セット型または校正ルールなどが含まれます。 暗黙的な型変換により、インデックスが使用できなくなったり、クエリ結果が不正確になったりする可能性があるため、使用時には慎重に識別する必要があります。 フィールドを定義するときは、数値型を int または bigint として定義することをお勧めします。テーブルがリンクされている場合、関連付けられているフィールドは同じ型、文字セット、および照合ルールを維持する必要があります。 最後に、暗黙的な型変換についての公式サイトの説明を掲載しておきます。
要約する 上記は、編集者が紹介したMySQLの暗黙的な変換です。皆様のお役に立てれば幸いです。ご質問がある場合は、メッセージを残してください。編集者がすぐに返信します。また、123WORDPRESS.COM ウェブサイトをサポートしてくださっている皆様にも感謝申し上げます。 以下もご興味があるかもしれません:
|
<<: Centos7のシステム言語を簡体字中国語に変更する方法
レンダリング下の画像のような効果を実現したい場合は、読み続けてアニメーション画像に直接進んでください...
wgetコマンドを使用して、親ディレクトリの下のサブディレクトリ全体をダウンロードします。親ディレク...
これにより、png ファイルのアップロードも不可能になりました (後で情報を調べたところ、レジストリ...
これは、データベース サーバーが、接続が多すぎるのを避けるために、一定時間非アクティブな状態が続くと...
1. 全体的な手順冒頭で、RabbitMQ サービスをインストールして実行する方法を紹介しましたが、...
適用シナリオ:新しい要件の 1 つはアンケート調査を行うことですが、必然的に多くの質問が含まれ、1 ...
目的リクエスト アクセス ボリュームを制御するための Nginx ngx_http_limit_co...
目次クエリの背景1. クエリをいいね2. JSON関数クエリ3. 共同インデックスクエリ4. 全文イ...
序文私は Win7 を搭載した古いラップトップを持っています。古いシステムを維持しながら、同時に U...
目次序文解決:ステップ1ステップ2序文環境: VMware Workstation 上に Linux...
目次背景関数目的アイデアの源成し遂げるセット得るプロパティの削除拡張機能を禁止するもっている要約する...
序文開発プロセスでは、すべてのデータではなく特定の期間内のデータをクエリするなど、クエリのフィルタリ...
導入コンパイル、インストール、問題の解決後、Nginx は正常に動作していますが、現時点では Ngi...
ネットワーク セキュリティは非常に重要なトピックであり、サーバーはネットワーク セキュリティにおける...
プロジェクト要件では、アップロードされたドキュメントの前処理が必要です。ユーザーが doc 形式でド...