0

该案是关于可以预订电影的客户。但在任何给定时间,他最多只能拥有 10 部电影。我需要什么检查约束才能让它工作?

创建我的数据库的代码如下:

CREATE TABLE Genre (PK_GenreID AUTOINCREMENT(13, 1) NOT NULL, GenreNaam TEXT(20),

主键(PK_GenreID));

创建唯一索引索引_BC00E533_C727_4D6E ON Genre(GenreNaam);

CREATE TABLE Klant (PK_Klantnummer AUTOINCREMENT(19, 1) NOT NULL, Naam TEXT(20) NOT NULL, Woonplaats TEXT(20), Postcode TEXT(6), Huisnummer TEXT(6), Telefoon TEXT(10), Email TEXT(255) ),

约束 PrimaryKey PRIMARY KEY (PK_Klantnummer));

在 Klant(Naam) 上创建唯一索引 Index_6827B6DC_E76F_4B57;

CREATE TABLE Reserveringen (PK_ReserveringID AUTOINCREMENT(13, 1) NOT NULL, FK_Klantnummer INTEGER, Reserveringsdatum DATE, PRIMARY KEY (PK_ReserveringID),

CONSTRAINT KlantReserveringen FOREIGN KEY (FK_Klantnummer) REFERENCES Klant(PK_Klantnummer) ON UPDATE CASCADE ON DELETE CASCADE);

CREATE TABLE Films (PK_FilmnaamID AUTOINCREMENT(51, 1) NOT NULL, FK_GenreID INTEGER, Filmnaam TEXT(30) WITH COMPRESSION, Releasedatum DATE, Regisseur TEXT(30), CONSTRAINT PrimaryKey PRIMARY KEY (PK_FilmnaamID),

CONSTRAINT GenreFilms FOREIGN KEY (FK_GenreID) REFERENCES Genre(PK_GenreID) ON UPDATE CASCADE ON DELETE CASCADE);

在电影上创建索引 PK_FilmnaamID(PK_FilmnaamID);

创建表 Beelddrager (PK_FilmID AUTOINCREMENT(50, 1) NOT NULL, FK_FilmnaamID INTEGER, Soort TEXT(50), 主键 (PK_FilmID),

约束 FilmsBeelddrager FOREIGN KEY (FK_FilmnaamID) REFERENCES Films(PK_FilmnaamID) ON UPDATE CASCADE ON DELETE CASCADE);

CREATE TABLE Beschadiging (PK_BeschadigingID AUTOINCREMENT(14, 1) NOT NULL, FK_FilmID INTEGER, Schade TEXT(255), Datum DATE, CONSTRAINT PrimaryKey PRIMARY KEY (PK_BeschadigingID),

CONSTRAINT BeelddragerBeschadiging FOREIGN KEY (FK_FilmID) REFERENCES Beelddrager(PK_FilmID) ON UPDATE CASCADE ON DELETE CASCADE);

在 Beschadiging(PK_BeschadigingID)上创建索引 PK_BeschadigingID;

CREATE TABLE Reserveringsregel (FK_ReserveringID INTEGER, FK_FilmID INTEGER, Begindatum DATE, Einddatum DATE, CONSTRAINT BeelddragerReserveringsregel FOREIGN KEY (FK_FilmID) REFERENCES Beelddrager(PK_FilmID) ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT ReserveringenReserveringsregel FOREIGN KEY (FK_ReserveringID) REFERENCES Reserveringen(PK_ReserveringID) ON UPDATE CASCADE删除级联);

4

1 回答 1

0

这条规则听起来不太适合数据库层强制执行。

参照完整性功能(它们的唯一键和外键)不能单独解决这个问题。

一种可能的解决方案是在尝试任何违反所需基数的插入、更新或删除时使用触发器来短路(抛出异常)。然而 mysql 在这方面的功能方面相当不足(取决于版本)。此外,触发器通常是一个坏主意,尤其是在执行您建议的波动业务规则时更是如此。

一个可能的解决方案是去规范化你的数据结构。但这是一个非常可怕的想法,我不会详细说明。

一个可能的解决方案是维护关于你的集合基数的元数据,然后利用元数据来强制改变。这变得棘手并最终失败,因为您的应用程序代码必须完美地保持此元数据最新。这种模式经常被实现,但同样经常失败。

最终,最好的解决方案是在应用程序代码中正确使用事务。一般流程是这样的:

  1. 知道你想在你的应用程序代码中进行什么插入/更新/删除
  2. 开始交易
  3. 锁定在基数上有业务规则限制的数据集
  4. 比较数据库状态与您要进行的更改
  5. 如果它通过了您的规则,则执行 SQL
  6. 提交交易
于 2013-06-20T20:59:50.840 回答