2

最近、私がサポートしているチームが、MySQL データベースに保存 (および取得) する値で問題に遭遇しました。彼らは、カンマ区切りの値を (VARCHAR(255)?) 列に格納していたと言っています。

彼らは、値が暗黙のうちに切り捨てられていることを報告し (コードはほとんどが Ruby で、その他の処理は Scala で行われています)、その列のサイズを 2 倍にするように依頼しました。

当然のことながら、正規化することを提案しました...これらの値 (以前はカンマ区切り) をそれぞれ別の行に格納し、SELECT を使用してセット (以前は単一の行でした) をフェッチします。彼らは反対し、他の種類のデータベースクエリに対してこれらの分離された値を決して望んでおらず、フィールドを新しい (512) 幅よりも広くする必要は決してないと主張しました.

次に、少なくとも文字列の終わりを示す番兵 (特に末尾のセミコロン) を追加し、すべてのフェッチでそれをチェックすることを提案しました。彼らはそれを実装しており、このアプローチに満足しています。

私の質問:

  • 彼らのデータはどのようにして静かに切り捨てられたのでしょうか? エラーを抑制している MySQL または Ruby の DB ドライバーに設定はありますか?
  • このセンチネルで終了した値と、より正規化されたアプローチの長所と短所は何ですか?
  • このセンチネル終了値の専門用語またはニックネームはありますか?
  • 彼らの問題に対処するためのより良い方法は何でしょうか?
4

2 に答える 2

1

MySQLで切り捨てを「見逃す」のは実際には非常に簡単ですが、役立つようにするのではなく、厳しく通知するようにするのも非常に簡単です。

MySQLマニュアルから:

厳密なSQLモードが有効になっておらず、列の最大長を超える値をCHAR列またはVARCHAR列に割り当てると、値が切り捨てられて警告が生成されます。スペース以外の文字を切り捨てる場合は、(警告ではなく)エラーを発生させ、厳密なSQLモードを使用して値の挿入を抑制することができます。5.1.6項「サーバーSQLモード」を参照してください。

マニュアルに示されているように、MySQLのいくつかの「厳密な」モードの1つを設定して、この状況でエラーを発生させることができます(そうでなければ、サイレントな切り捨てまたは置換値を引き起こす他の多くのモード)。

于 2012-04-25T01:27:58.357 に答える
1

データベースで厳密モードが有効になっていない場合、MySQL は列に収まらない文字列をvarchar(n)切り捨て、切り捨てに関する警告のみを生成します。厳密モードを有効にすると、そのような場合にエラーが発生します (より安心できます)。

センチネル値の大きな問題は、読み取り時にのみチェックしていることです。つまり、無効なデータや壊れたデータを保存する可能性があります (そして確実にそうなるでしょう) が、そのデータを解凍しようとするまで問題についてはわかりません。しかし、データをアンパックしているときに、失われたものを回復するには遅すぎます。

さまざまなより良いアプローチがあります。

  1. 適切に正規化されたテーブル。
  2. MySQL で厳密モードを有効にします。
  3. 挿入前または更新前の長さの検証。
  4. 彼らが実際に Rails を使用している場合はserialize、データを ( cringe ) YAML との間で自動的に変換するために使用できます。この場合、より大きな TEXT 列タイプを使用する必要があり、それでも切り捨ての問題が発生します。

したがって、 23はすぐに実行する必要があります。1が最適で、標準化を恐れている (または理解していない) 場合は4が中間の選択肢かもしれません。

于 2012-04-25T01:31:27.433 に答える