3

我在 SQL Server 中有一个非常简单的数据库,其中包含以下三个表:

  • TheaterID, is3D,其他值...)
  • ShowID, Theater_ID, Movie_ID, date, time,其他值...)
  • MovieID, is3D,其他值...)

我想确保3D 电影只能在 3D 影院中播放。仅在 2D 影院中的 2D 电影,并且只能通过外键(无触发器等)进行。

4

1 回答 1

3

要仅通过外键执行此操作,您还需要添加一is3DShow以及几个逻辑上冗余的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 回答