0

私は SQL にかなり慣れていないので、テーブルで外部キーを使用するのに問題があります。そのようなテーブルの 1 行を挿入/更新するには、多くのクエリが必要です。

したがって、基本的に、IRC チャネルの「キー = 値」関係を格納するために使用する 4 つのテーブルの構造があります。

msg
  -id integer //primary key
  -srv_id     //integer
  -chan_id    //integer
  -usr_id     //integer
  -key        //text
  -value      //text

.

srv
  -id   //integer primary key
  -name //text

.

chan
  -id   //integer primary key
  -name //text

.

usr
  -id   //integer primary key
  -name //text

msg テーブルの srv_id、chan_id、および usr_id は、次の 3 つのテーブルからの外部キーです。

ユーザーは他のキーを上書きできることに注意する必要があるため、ユーザーが「キー = 値」関係を追加するときは、msg テーブルに新しい行を挿入するか、指定された srv_name、chan_name、およびキーの既存の値と usr_name を更新する必要があります。

質問: msg.key = 'some_msg_key', msg.value = 'new_msg_value', srv.name = 'some_srv_name', chan. .name = 'some_chan_name' および usr.name = 'some_usr_name' は、まだテーブルに含まれていない可能性があります。

今、私は次のようなことをしています:

SELECT id FROM srv WHERE name = 'some_srv_name'

ID を取得したかどうかを確認します。取得していない場合は確認します

INSERT INTO srv WHERE name = 'some_srv_name'

そして、私はそれのIDを取得します

SELECT id FROM srv WHERE name = 'some_srv_name'

次に、chan テーブルと usr テーブルに対して同じことを行います。
srv、chan、urs の名前がまったく新しい場合は、9 つ​​のクエリです。それは恐ろしいことではありませんか?これで終わりではありません。私の目標は、新しい行を msg テーブルに追加するか、存在する場合は更新することです (キー値に基づいて)。

そのため、「some_srv_name」、「some_chan_name」、および「some_usr_name」がテーブルにあることがわかり、それらの ID を取得したら、そのような ID とキー値 =「some_msg_key」を持つ行が存在するかどうかを確認します。

SELECT id FROM msg WHERE srv_id = 'id_from_previous_queries' AND chan_id = 'id_from_previous_queries' AND key = 'some_msg_key'

何かを取得した場合、行が存在することがわかっているので、更新する必要があるので、次のようにします。

UPDATE msg SET usr_id = 'id_from_previous_queries', key = 'some_msg_key', value = 'new_msg_value' WHERE id = 'id_from_right_above'

何も得られない場合は、そのような行がないことがわかり、挿入する必要があります。

INSERT INTO msg VALUES(null, 'id_from_previous_queries', 'id_from_previous_queries', 'id_from_previous_queries', 'some_msg_key', 'new_msg_value')

したがって、合計で 5 ~ 11 のクエリを実行します。

まだテーブルにない可能性のあるsrv、chan、およびusrの名前だけを知っているmsgテーブルの行を追加/更新するためのより少ないクエリでより良い方法があるかどうか疑問に思います。

注:私はSQLiteを使用しています

4

2 に答える 2

1

はい、もっと簡単にできます。最初にルックアップ テーブルを作成し、次に最終的な msg テーブルを作成します。テーブル src に正規化されていないデータがあり、それを挿入したいとします。

まず、次のようなクエリを使用して、各ルックアップ テーブルに新しい値を挿入する必要があります。

insert into srv(name)
    select distinct name
    from src
    where name not in (select name from srv)

ID は、自動インクリメント/ID/シリアル列であると宣言することにより、自動的に割り当てられる必要があります (データベースによって異なります)。

これをルックアップ テーブルごとに行います。次に、次のようにして msg テーブルに挿入します。

insert into msg(srv_id, chan_id, usr_id, key, value)
    select srv.srv_id, chan.chan_id, . . . 
    from src join
         srv
         on src.name = srv.src_name join
         chan
         on chan.name = srv.chan_name . . .
于 2012-07-09T14:49:08.180 に答える
0

主キーの値を変更する必要はありません。ストアド プロシージャとトリガーの操作方法を調べる必要があります。

于 2012-07-09T14:47:18.160 に答える