2

次の空の SQL テーブルに「アーノルド シュワルツェネッガー」と「ハスタ ラ ビスタ ベイビー」を挿入するには、どのようなステートメントを使用すればよいでしょうか?

この質問のタイトルは当初、「双方向の関連付けと自動生成された整数 PK を使用して最初のレコードを SQL テーブルに挿入する方法は?」というものでした。しかし、それが正しい言い回しであるかどうかはわかりませんでした... 基本的に、2 つのテーブルActorsCatchPhrases.

Actors次のようになります。

  ActorId                  int             NOT NULL  PK (autogenerated by db)
  FavoriteCatchPhraseId    int             NOT NULL  FK
  Name                     varchar(200)    NOT NULL

CatchPhrases次のようになります。

  CatchPhraseId            int             NOT NULL  PK (autogenerated by db)
  ActorId                  int             NOT NULL  FK
  PhraseText               varchar(500)    NOT NULL

したがって、アクターは複数のキャッチ フレーズを持つことができますが、少なくとも 1 つ持つ必要があります。キャッチ フレーズは俳優に関連付けられます。現在、どちらのテーブルにもデータはありません。

4

3 に答える 3

5

双方向の関係を避けるために、別の方法でモデル化します(これは実行が困難です)。列(IsFavorite)をCatchPhrasesテーブルに追加するだけです。コードで制約またはビジネスルールを使用して、各アクターのお気に入りとしてマークされたキャッチフレーズの数を1つに制限します。

俳優:

ActorId                  int             NOT NULL  PK (autogenerated by db)
Name                     varchar(200)    NOT NULL

キャッチフレーズ:

CatchPhraseId            int             NOT NULL  PK (autogenerated by db)
ActorId                  int             NOT NULL  FK
PhraseText               varchar(500)    NOT NULL
IsFavorite               bit             NOT NULL

アクターのキャッチフレーズをすばやく見つけることができるように、CatchPhrasesテーブルのActorIdにインデックスがあることを確認してください。

または、結合テーブルを使用します。これにより、複数のアクターが同じキャッチフレーズを持つことができます。

俳優:

ActorId                  int             NOT NULL PK (autogenerated by db)
Name                     varchar(200)    NOT NULL

ActorCatchPhrases

ActorId                  int             NOT NULL PK (FK to Actors)
CatchPhraseId            int             NOT NULL PK (FK to CatchPhrases)
IsFavorite               bit             NOT NULL

キャッチフレーズ

PhraseId                 int             NOT NULL PK (autogenerated by db)  
PhraseText               varchar(500)    NOT NULL
于 2011-03-05T17:35:35.570 に答える
2

ルール、つまり親レコードには少なくとも1つの子レコードが必要であるという規則は、宣言型の参照整合性で強制することはできません。

「Favorite」は単数形であるため、FavoriteCatchPhraseは、Actorエンティティの属性、つまりActorsテーブルの列である可能性があります。フレーズのテキストを保存できます。しかし、お気に入りのキャッチフレーズは、真に「キャッチー」であることが精査され、認められた一連の正真正銘のキャッチフレーズからのものでなければならないというルールを適用したい場合は、あまり覚えていないことわざではありません。 CatchPhrasesテーブルがあり、Actor.FavoriteCatchPhraseにフレーズIDと参照CatchPhrasesテーブルを外部キーとして保存させることができますが、Actor.FavoriteCatchPhraseに一意のインデックスを付けない限り、複数のアクターが同じキャッチフレーズを使用できます。

于 2011-03-05T19:53:48.887 に答える
1

「ダーティリード」(コミットされていない読み取り)を使用して、トランザクション内でこれを行うことができると思います。

しかし、たとえ可能であったとしても、それはあまり良くありません。

@tvanfosson が提案したように、最もクリーンな方法は、CatchPhrases テーブルの ActorId 列の FK をオフにすることです。

最初にダミーの CatchPhrases (ID 挿入をオンに設定) 行を次のように作成します。

0 - 0 - '好きなキャッチフレーズがない', 0

次に、Actors 行を挿入する場合、使用するデフォルトがあります。

(アイデンティティ) - 0 - 「アーノルド・シュワルツェネッガー」

次に、変数を、Actors の挿入によって生成される @@identity 値に設定します。

それからキャッチフレーズ:

(identity) - (variable) - 「Hasta la vista baby」

次に、CatchPhrases 挿入によって生成される @@identity 値に変数を設定し、それを使用してアクター行のキャッチフレーズ ID を更新します。

……ふぅ、このデザインでよろしいですか?

編集

まぁ、デザイン変えれば…

関係を見ると、Actor は多くの Catchphrases を持つことができ、Catchphrases は多くの Actor を持つことができます。そのため、多対多の設計があり、通常はリンク エンティティを使用してリファクタリングされます (MSDN ではこれをジャンクション テーブルと呼んでいます)。

Actors   
  |
-----
| | |
ActorsCatchphrases
| | |
-----
  |
Catchphrases
  • アクターには、アクター名とアクターの詳細があります (キャッチフレーズへの参照はありません)。
  • ActorsCatchphrases には ActorId と CatchphraseId があり、その俳優のお気に入りかどうかに関するブール値があります。
  • キャッチフレーズには、キャッチフレーズの詳細があります (俳優への言及はありません)。
于 2011-03-05T18:01:54.167 に答える