数値データ型でMySQLデータベースにクエリを書き込む正しい方法は何ですか?
SELECT * FROM accounts WHERE id = 5;
また
SELECT * FROM accounts WHERE id = '5';
'
テキストデータ型との一貫性が高いため、主に最後のものを使用します。
パフォーマンスに影響しますか?
数値データ型でMySQLデータベースにクエリを書き込む正しい方法は何ですか?
SELECT * FROM accounts WHERE id = 5;
また
SELECT * FROM accounts WHERE id = '5';
'
テキストデータ型との一貫性が高いため、主に最後のものを使用します。
パフォーマンスに影響しますか?
引用符は文字列用です。MySQLはそれらの引用符を読み取って整数にキャストします。これは低速で、最初にintを渡すだけです。
正直なところ、パフォーマンスの違いはわずかですが、数値を文字列に格納し、数学を行う必要があるときにintにキャストするプログラムを作成するのと同じです。これは悪い習慣です。
2つのクエリの速度の顕著な違いを測定できるとは思えません。パフォーマンスを気にする場合は、id
列にインデックスがあることを確認する必要があります。そうすると、両方のクエリが非常に高速になります。
ただし、セキュリティ上の考慮事項があります。
MySQLの公式意見
MySQLクライアントのセキュリティガイドラインでは、引用符を使用することを推奨しています。
よくある間違いは、文字列データ値のみを保護することです。数値データも確認することを忘れないでください。ユーザーが値234を入力したときに、アプリケーションがSELECT * FROM table WHERE ID = 234などのクエリを生成する場合、ユーザーは値を入力して
234 OR 1=1
、アプリケーションにクエリを生成させることができますSELECT * FROM table WHERE ID=234 OR 1=1
。その結果、サーバーはテーブル内のすべての行を取得します。これにより、すべての行が公開され、サーバーに過度の負荷がかかります。このタイプの攻撃から保護する最も簡単な方法は、数値定数を一重引用符で囲むことですSELECT * FROM table WHERE ID='234'
。
強調鉱山。
私の意見
ドキュメントでは引用符の使用が推奨されていますが、説明されている攻撃を防ぐために必要でも十分でもありません。たとえば、攻撃者の文字列をに変更すると、攻撃者の234' OR '1'='1
アプローチが無効になります。
私の意見では、アプリケーションを安全にするためのより良い方法は、ユーザー値を文字列に直接入れるのではなく、パラメーター化されたクエリを使用することです。
何らかの理由でパラメーター化されたクエリを使用できない場合は、引用符を使用しないでください。ただし、intval
関数を使用して、変数に実際に整数が含まれていることを確認してください。
idのタイプに応じて、「5」または5のいずれかを使用できます。通常、idは主キーであり、int型であるため、5を使用する必要があります。
データベースのフィールドタイプが文字列の場合は、引用符を使用します。それ以外の場合、数値の場合は引用符を使用しないでください。数値フィールドタイプに引用符を使用すると、mysqlが文字列を数値に一致させる必要があるため、クエリの速度が大幅に低下する可能性があります。
タイプが数値として定義されている列に対して引用符で囲まれた数値を使用すると、サーバーはクエリのコンパイル中に文字列を正しいタイプに変換する必要があるため、引用符で囲まれていない値を使用する場合と比較して、パフォーマンスが低下します。それ以外は効果がなく、ヒットを測定するのは難しいでしょう。(「0」と0の両方が文字列としてサーバーに送信されるため、使用する前にフィールドの内部タイプに変換する必要があることに注意してください。「0」を送信すると、追加のステップが強制されるだけです。最初にパーサーが解析します。 「0」の場合、オプティマイザは列タイプが数値であることを認識し、それに応じて変換します。OTOH、0を指定すると、パーサーはそれを数値として解析し[long int iircとして格納]、フィールドのタイプを認識し、変換します。必要に応じて、適切なフィールドタイプの数値になります。したがって、違いは実際には重要ではありません)。
ただし、タイプがテキストとして定義されている列に対して引用符で囲まれていない数値を使用することは、サーバーが列のインデックスを使用してクエリを解決できないことを意味するため、非常に悪い考えです。
特定の文字列は正確に1つの数値に数値化されますが、特定の数値に数値化されるほぼ無限の文字列のセットがあることを理解することが重要です。「0」、「0E0」、「0.0」などを検討してください。これは、フィールドが数値の場合に制約を引用することがそれほど悪くない理由を説明し、実行する操作のみがあり、フィールドがフィールドの場合に制約を引用しないことが悪い理由を説明します。は数値ではありません。これは、サーバーが比較を行う前にテーブル内の各文字列を数値にキャストする必要があるため、テーブルスキャンを強制するためです。