【问题标题】:Foreign key constraint to cross check user rows in MySQLMySQL中交叉检查用户行的外键约束
【发布时间】:2021-02-02 14:22:28
【问题描述】:

只有当外键数据实际上属于正在执行插入/更新的用户时,我才能使用外键强制插入/更新查询成功。

例如,用户 1 创建的类别不能被用户 2 使用,反之亦然以禁止交叉访问。

Create Table Users(
    user_id int not null AUTO_INCREMENT,
    user_name varchar(50) not null,
    city varchar(50) default null,
    PRIMARY KEY (user_id)
);

-- Insert users
Insert into Users(user_name, city) Values('Nick', 'New york');
Insert into Users(user_name, city) Values('John', 'Seattle');

创建类别

Create Table Categories(
    category_id int not null AUTO_INCREMENT,
    user_id int not null,
    category_name varchar(50) not null,
    PRIMARY KEY (category_id),
  CONSTRAINT FK_CategoryUser FOREIGN KEY (user_id) REFERENCES Users(user_id)  
);

-- Insert category for Nick with user_id = 1
Insert into Categories(user_id, category_name) Values(1, 'Travel');

-- Insert category for John user_id = 2
Insert into Categories(user_id, category_name) Values(2, 'Science');

创建书籍

Create Table Books(
    book_id int not null AUTO_INCREMENT,
    user_id int not null,
    category_id int default null,    
    book_name varchar(50) not null,
    book_type varchar(50) not null,
    PRIMARY KEY (book_id),
  CONSTRAINT FK_BookUser FOREIGN KEY (user_id) REFERENCES Users(user_id),
  CONSTRAINT FK_BookCategory FOREIGN KEY (category_id) REFERENCES Categories(category_id)
);

现在为尼克插入书必须失败,因为带有category_id = 2 行的“科学”类别属于带有user_id = 1 的约翰

Insert into Books(user_id, category_id, book_name, book_type)
Values(1, 2, 'My science book', 'online')

【问题讨论】:

  • ALTER TABLE Books ADD UNIQUE KEY (category_id); 这使得 Books 中的多行具有给定的 category_id 是错误的。因此,每个类别只能有一个用户使用。
  • @BillKarwin 那不正确。拥有此类别的用户应该能够为该类别添加更多书籍,因此不能使其独一无二。我只需要限制不属于该类别的其他用户。

标签: mysql sql amazon-rds


【解决方案1】:

既然你有Categories.user_id,你可以把它作为一个键:

ALTER TABLE Categories ADD UNIQUE KEY (user_id, category_id);

然后从 Books 表中引用它:

ALTER TABLE Books ADD FOREIGN KEY (user_id, category_id) 
  REFERENCES Categories (user_id, category_id);

这要求只有在为用户分配了相应类别的情况下才向用户提供一本书。但它允许 Books 中的多行具有相同的用户和类别对。

将 Categories 中的新键设为 UNIQUE KEY 似乎是多余的,因为仅 category_id 就已经是唯一的了。但在一般 SQL 语言中,外键必须引用 UNIQUE KEY。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-09
    • 2021-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多