1

私は持っているテーブルproviderを持っていますid|provider_name|url
私は持っている別のテーブルuserを持っていますid|name|provider_id

create_user(name,provider_name)そのプロバイダー名のプロバイダーが存在するかどうかをチェックする関数を作成したいと思います。存在する場合は、行を挿入し、最後の行IDを返します。それ以外の場合は戻り0ます。provider_id->に外部キーの整合性を設定しましたuser.id。両方のフィールドidpkeyserial

insert into users
  (name, provider_id)
values($1, (
    select id from provider where name = $2
)) returning id

それは大丈夫ですか ?

4

2 に答える 2

1

あなたの声明

INSERT INTO users (name, provider_id)
VALUES ($1, (SELECT id FROM provider WHERE name = $2))
RETURNING id;

users.provider_idを作成すると機能しますNOT NULLNULLそれがないと、存在しないprovider_idの値を入力することになります。外部キー制約はこれを禁止していません!
(私はあなたが意味したと思います:provider_id -> provider.idではなく-> user.id。)

users.name UNIQUE名前の重複を禁止する場合としない場合があります。

一意の名前を使用する場合でも、ほとんどの場合、代理主キー(user.id)は意味をなします。整数の処理は、(長い)テキストの処理よりも高速です。特に、テーブルの主キーを参照する他のテーブルが複数userある場合は、通常はそうです。外部キーとそれに付随するインデックスに整数を使用すると、かなり高速になり、ディスクとRAMに必要なスペースが少なくて済みます。nameまた、とに分割するfirstnameなど、後で変更を加えるのも簡単ですsurname

于 2012-04-14T00:09:04.937 に答える
0

その名前のユーザー行が複数ある場合は機能しません。ユーザー間で名前を重複させることができない場合は、問題ありません。(それが本当に名前である場合、重複が不可能であると想定するのは賢明ではないようです。)

もちろん、重複するユーザー名が不可能な場合は、ユーザーテーブルにid列を設定する正当な理由はありません。名前を主キーにし、id列を省略しておくことを強くお勧めします。(他の名前でも呼ばれる可能性があります。)これにより、クエリのクラス全体とともに、このクエリが簡素化および高速化されます。このスキーマ設計では、1人のユーザーが最大で1つのプロバイダー(provider_idがnull対応の場合)または正確に1つのプロバイダー(provider_idがNOT NULLの場合)を持つことができることも前提としています。

于 2012-04-07T20:18:37.150 に答える