0

次のように、複数の写真を家屋に関連付ける MSSQL Server 2008 テーブルがあります。

HouseID - with foreign key to House table
PhotoID - with foreign key to Photo table

写真を複数の家に関連付けることができないように、PhotoID に独自の制約があり、すべてうまく機能しています。

家の記録のデフォルトの写真を指定したいと思います。テーブルはそのように更新されます

HouseID
PhotoID
isDefault

問題は、家の一連の写真に対して isDefault = 1 が 1 つしか存在できないことです。

MSSQL Server 2008 で、特定のハウス ID に対して isDefault = 1 が 1 つだけ存在し、他のレコードが isDefault = 0 であることを確認するにはどうすればよいですか? トリガーを使用する方が良いですか、それともより良い方法がありますか? トリガーの場合、最適化を確実にするための構文に関する提案はありますか?

最後に、Insert イベントと Update イベントで機能するには、これが必要です。

アップデート:

以下は魅力のように機能しました。コメント?

CREATE VIEW HousePhoto_isDefault AS 
SELECT yourSchema.HousePhoto.houseID, yourSchema.HousePhoto.isDefault
FROM yourSchema.HousePhoto WHERE isDefault = 1
GO

CREATE UNIQUE CLUSTERED INDEX idx_HousePhoto_isDefault
ON HousePhoto_isDefault (houseID)
GO
4

4 に答える 4

0

MSSQL Server 2008 で、特定のハウス ID に対して isDefault = 1 が 1 つだけ存在し、他のレコードが isDefault = 0 であることを確認するにはどうすればよいですか?

Yves Samèrがこの回答で指摘したように 、フィルターされたインデックスを使用できるのはなぜですか

CREATE UNIQUE INDEX photo_isDefault 
    ON Photos(HouseID) WHERE isDefault = 1 

デモ

生成されるエラーは

一意のインデックス 'photo_isDefault' を持つオブジェクト 'dbo.Photos' に重複するキー行を挿入できません。: INSERT INTO Photos (houseID, isDefault) VALUES (1,1)

INDEXED VIEW の使用を選択することもできますし、前述のようにトリガーも使用できます。

于 2013-04-15T21:11:15.373 に答える
0

別のアプローチがあります:「逆」FKを使用します:

小胞体モデル

[SQLフィドル]

識別関係の使用法と、結果として得られる複合 PK のPhoto:に注意することが重要です{HouseId, PhotoNo}。これには次の 2 つの目的があります。

  • 写真がある家のデフォルトである場合、同じ家に属している必要があります。
  • FK をHouseコンポジットにします。FK フィールドの 1 つが PK にもあるため ( )、NULL にすることはできません。そのため、NULL にすることができるHouseId別のフィールドを持つことが重要です( )。FK フィールドのいずれかが NULL の場合、FK は強制されないため、そのような循環 FK が存在する場合に新しいデータ1を挿入するときに鶏が先か卵が先かという問題を解決できます。DefaultPictureNo

フラグと関連するフィルター処理されたインデックスを使用する場合と比較するとisDefault、このアプローチには次のトレードオフがあります。

  • PRO: 余分なフィールドのオーバーヘッドを回避します。これは、既定の画像の数に比べて画像の総数が非常に多い場合に重要になる可能性があります。
  • 短所: PhotoPK に自動インクリメントを使用することは実用的ではありません。
  • CON: このような循環 FK が存在する状態で、宣言型の参照アクション (ON DELETE CASCADE など) を使用しようとすると、MS SQL Server が文句を言います。トリガーを使用して参照アクションを実装する必要があります。これは、一般的に他の DBMS には当てはまらない MS SQL Server の癖です。
  • TIE: でのクラスタリングへの干渉は少なくなりますが、 でのクラスタリングPictureの干渉は大きくなりますHouse2
  • PRO: フィルター選択されたインデックスをサポートしていない DBMS に適用できます (ここではそれほど重要ではありませんが、言及する価値があります)。

1 Ie を使用すると、デフォルトの画像をすぐに設定せずに家を挿入できますが、これは新しい家であり、まだ画像がないため不可能です。

2クラスター化されたテーブルではセカンダリ インデックスが高価になる可能性があり、FK にHouseはサポート インデックスが必要になります。

于 2013-04-16T15:04:29.317 に答える
0

あなたが説明したように、トリガーを使用する必要があります。

ただし、データ構造を少し変更すると、通常の制約でそれを行うことができると思います。isDefault写真レベルで保管するのではなくDefaultPhotoId、家レベルで保管してください。そうすれば、何をしても、複数のデフォルトの写真を持つことはできません。

デフォルトがあることを確認したい場合は、 として設定しますNOT NULL

于 2013-04-15T20:51:36.297 に答える