3

SQL Server に非常に単純なデータベースがあり、次の 3 つのテーブルがあります。

  • Theater(ID, is3D,他の値...)
  • Show(ID, Theater_ID, Movie_ID, date, time,他の値...)
  • Movie(ID, is3D,他の値...)

3D 映画は 3D シアターでのみ再生できるようにしたいと思います。2D 映画は 2D シアターでのみ、外部キーのみで実行します (トリガーなどはありません)。

4

1 に答える 1

3

外部キーだけでこれを行うには、is3D列を追加し、論理的に冗長な制約Showをいくつか追加する必要があります。UNIQUE

CREATE TABLE Theater
  (
     ID   INT PRIMARY KEY,
     is3D BIT NOT NULL,
     /*Other columns*/
     UNIQUE(ID, is3D)
  )

CREATE TABLE Movie
  (
     ID   INT PRIMARY KEY,
     is3D BIT NOT NULL,
     /*Other columns*/
     UNIQUE(ID, is3D)
  )

CREATE TABLE Show
  (
     ID         INT PRIMARY KEY,
     Theater_ID INT NOT NULL,
     Movie_ID   INT NOT NULL,
     is3D       BIT NOT NULL,
     /*Other columns*/
     FOREIGN KEY(Theater_ID, is3D) REFERENCES Theater (ID, is3D),
     FOREIGN KEY(Movie_ID, is3D) REFERENCES Movie (ID, is3D)
  ) 

以下のように、追加の列や一意の制約を必要とせずに、インデックス付きビューを使用してこれを宣言的に適用することもできます。

CREATE TABLE dbo.TwoRows
  (
     X INT PRIMARY KEY
  );

INSERT INTO dbo.TwoRows
VALUES      (1), (2)

GO

CREATE VIEW V
WITH SCHEMABINDING
AS
  SELECT S.Theater_ID,
         S.Movie_ID
  FROM   dbo.Show S
         JOIN dbo.Theater T
           ON S.Theater_ID = T.ID
         JOIN dbo.Movie M
           ON S.Movie_ID = M.ID
         CROSS JOIN dbo.TwoRows
  WHERE  T.is3D <> M.is3D

GO

CREATE UNIQUE CLUSTERED INDEX IX
  ON V(Theater_ID, Movie_ID) 

ルールが満たされている場合、基礎となるクエリは常に行を返さないようにする必要があります。いずれかの行返された場合、クロス結合dbo.TwoRowsによって乗算され、一意の制約違反が発生し、状況が防止されます。

于 2013-06-02T20:19:14.703 に答える