11

私は自分のデータベース(Oracle)を設計する必要があるプロジェクトのこの時点にいます。通常、ステータス テーブルと国テーブルでは、数値の主キーは使用しません。たとえば、

STATUS (max 6)
AC --> Active
DE --> Deleted

COUNTRIES (total 30)
UK --> United Kingdom
IT --> Italy
GR --> Greece

これらのテーブルは静的であり、アプリケーションを通じて更新されず、将来変更されることは予測されないため、これらの値を外部キーとして使用するテーブルで更新の問題が発生する可能性はありません。

アプリケーションのメイン テーブルは、ステータスと国 (複数回、例: 出発地の国、目的地の国) を使用し、年間 600000 行が追加されることが予想されます。

私の質問は、これらの VARCHAR(2) キーは、3 つのテーブルの結合をクエリするときにパフォーマンスに影響を与えるでしょうか。最初のものは 2 番目のものよりも大幅に遅くなりますか?

SELECT m.*,
       s.status_name,
       c.country_name
  FROM main m, status s, countries c
 WHERE m.status_cd = s.status_cd
   AND m.country_cd = c.country_cd
   AND m.status_cd = 'AC'
   AND m.country_cd = 'UK'

SELECT m.*,
       s.status_name,
       c.country_name
  FROM main m, status s, countries c
 WHERE m.status_cd = s.status_cd
   AND m.country_cd = c.country_cd
   AND m.status_cd = 1
   AND m.country_cd = 2

説明:

ステータスはバイナリではありません (テーブル名の横にある「最大 6」)。値はおそらく次のようになります。

* active
* deleted
* draft
* send
* replaced

デコードされた値をユーザーに表示する必要があるため、名前が必要です。

4

4 に答える 4

5

ステータス テーブルと国テーブルはどちらも非常に小さいため、正式にそのように記述されているかどうかにかかわらず、実際にはメモリ常駐になります。実際、外部キーは通常、参照される主キー フィールドのインデックスを必要とすることを除いて、テーブルのインデックスを気にしたくないかもしれません。

異なるタイプの結合間のパフォーマンスの違いはごくわずかであり、格納するデータが「より多く」あるため、数値コードはどちらかといえば遅くなります (ただし、すべてが非常に小さいため、無視できます)。

したがって、自然なコードを使用してください。それ以外はすべて別として、最初の例の SQL はより明確です。「UK」と「AC」は、1 と 2 よりもはるかに意味があります。

Oracle 以外の DBMS では、おそらくステータスと国コードの値の両方に CHAR(2) を使用します。Oracle ユーザーは、すべてに VARCHAR2 を使用する傾向があります。特に列の値が固定長であるため、代わりに CHAR(2) 列を使用することにペナルティがあるかどうかはわかりません。(たとえば、Informix では、VARCHAR(2) フィールド (最大 2 文字のフィールド) は、3 バイト、長さ (この場合は常に 2)、および 2 データ バイトとして格納されます。対照的に、CHAR(2) ) フィールドは 2 バイトしか占有しません。)

于 2008-11-27T17:20:17.923 に答える
2

このリンクをチェックしてください。要するに、varchar と num の間にパフォーマンスの違いはあまりありません。したがって、列にとって意味のある方を選択する必要があります。ここでは、varchar の方が理にかなっているようです。

于 2008-11-27T17:08:16.623 に答える
0

この場合、どの方法を選択してもかまいません。重要な部分は、データベース全体で同じ種類を使用し、ID 規則に一貫性を持たせることです。

于 2008-11-27T17:17:30.380 に答える
0

「ステータス」が(そして常にそうなるでしょうか?)バイナリのアクティブ/削除されたフィールドである場合、なぜテーブルを気にする必要がありますか。正規化が非現実的な極端に行われたようです。

tinyint(1) フィールドを単純に使用して、アクティブ/削除状態を 1 または 0 として記録する方が、簡単なことは言うまでもありません

これにより、結合の 1 つが完全になくなります。これは良いことです。

于 2008-11-27T16:36:43.083 に答える