2016-05-19 10 views
2

現在のデータベーステーブルを正規化する方法についていくつかアドバイスが必要です。長い文字列でデータベースの正規化を行う方法は?

現在のスキーマは次のようになります。

+----------+---------------+------+-----+---------+-------+ 
| Field | Type   | Null | Key | Default | Extra | 
+----------+---------------+------+-----+---------+-------+ 
| date  | date   | YES | MUL | NULL |  | 
| hostname | varchar(255) | YES |  | NULL |  | 
| username | varchar(255) | YES | MUL | NULL |  | 
| path  | varchar(1024) | YES | MUL | NULL |  | 
| count | int(11)  | YES |  | NULL |  | 
+----------+---------------+------+-----+---------+-------+ 

pathは長い文字列であり、それは多くの場合、同じ値で何度も繰り返されます。私はそれを別のテーブルに移動し、現在のテーブルの外部キーとして扱います。これは現在、毎週30Mのレコードを持っているので、多くのディスク容量を節約できます。

問題は、私がPathと呼ばれる別のテーブルにデータを挿入するとき、私は何とかパスが存在するかどうかを知る必要があるということです。そうであれば、既存のエントリを取得し、FKとして新しいエントリを現在のテーブルに割り当てます。そうでない場合はPathテーブルに新しいパスエントリを作成します。私はpathフィールドをPathテーブルにユニークにすることを考えましたが、mysqlはそれを許可せず、Specified key was too long; max key length is 1000 bytesエラーを返します。

私の質問は次のようになります。パスの値が別のテーブルに存在するかどうか

  • もしそうなら

    1. チェックすると、FKとしてそのIDを取得して作成します。何がこれを行うための最善の方法です現在のテーブル内の現在のテーブルのエントリ
    2. ない場合は、新しいパスエントリを作成し、FKとPKを取得し、エントリを作成

    フォロー質問:

    今すぐデータ挿入を行うINSERT INTO SQL文を作成するために、長い文字列連結を行っています。テーブルを分割すると、挿入が行われる前にルックアップを行う必要があるように思えます。私はプロセスがかなり遅くなると思います。それを避ける方法はありますか?

  • 答えて

    3

    まず、文字列を代理ID番号に置き換えると、正規化ではなくデータ圧縮が行われます。通常の書式では、文字列を数字で置き換える必要はありません。

    私はユニークなパステーブルにパスフィールドを作りについて考えたが、MySQLはそれを許可し、Specified key was too long; max key length is 1000 bytesエラーを与えていません。

    まあ、Path.path にはが一意である必要があります。いくつかの選択肢があります。

    • 長い値に一意性制約を強制するDBMSに代わり1024
    • スイッチのパス1000バイトにします。 PostgreSQLが動作します。
    • データベースレベルで一意性を強制するのではなく、アプリケーションレベルで一意性をチェックします。競合状態に注意してください。重複したパスのレポートをサポートするコードを記述します。 (「重複パスのレポートを印刷する」のように)最終的には、重複パスが見つかります。

    最も一般的なアプローチは、行を挿入するストアドプロシージャを呼び出すことです。 SPは最初にチェックしません。行を挿入するだけで重複キーによって発生したエラーがトラップされます。とにかくエラーをトラップする必要があります。重複キー以外にも多くのことが間違っている可能性があります。

    挿入が成功すると、SPは新しいID番号を返します。重複したキーエラーで失敗すると、既存のパスのID番号を選択し、代わりにそのパスを返します。他のエラーで失敗した場合の対処方法は、アプリケーションによって異なります。

    最初に確認してから挿入すると、挿入するたびにデータベースに2回往復する必要があります。最初に挿入してエラーをトラップすると、新しい行に対して1つの丸チップしか必要ありません。これにより、負荷が少し軽減されます。あなたがやっていることにもよりますが、たくさんあります。

    +0

    マイクさん、私はSPを使用し、データベースにヒットする時間を減らすというコンセプトが好きです。 –

    関連する問題