无法在两个表之间创建关系

时间:2014-01-28 12:17:37

标签: mysql sql relation

我有两张桌子:

CREATE TABLE `Users` (
  `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(50) NOT NULL DEFAULT '',
  `last_name` varchar(50) NOT NULL DEFAULT '',
  `login` varchar(50) NOT NULL DEFAULT '',
  `password` varchar(50) NOT NULL DEFAULT '',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;

CREATE TABLE `Books` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(50) NOT NULL DEFAULT '',
  `author` varchar(50) NOT NULL DEFAULT '',
  `year` int(4) NOT NULL,
  `available` int(3) NOT NULL DEFAULT '0',
  `availabledate` date NOT NULL,
  `user_id` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

我正在尝试在这两者之间建立关系,这样一个用户可能会有多本书(user_id),但无论我在做什么,我都会遇到错误。任

  

无法添加或更新子行:外键约束失败   (bookstore。,   约束books_fk外键(user_id)参考users   (user_id)ON UPETE CASCADE ON UPDATE CASCADE)

或之前我没有在Books表中使用unsigned int,我说默认值是0(我会优先但我不认为我可以这样做?)在这种情况下我得到错误150. / p>

3 个答案:

答案 0 :(得分:2)

我建议您更改数据库架构。为什么呢?

  1. 没有用户可以存在一本书吗?如果是,您不应该从引用用户的书籍中获得外键。用户可以在没有书籍的情况下存在吗?如果是,则不应该有来自引用书籍的用户的外键。

  2. 用户可以拥有多本图书吗?还有一本书有多个用户?如果是,您有m:n关系。这意味着您需要一个桥接表。

  3. 在表格中,您不需要外键:

    CREATE TABLE `Users` (
      `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `first_name` varchar(50) NOT NULL DEFAULT '',
      `last_name` varchar(50) NOT NULL DEFAULT '',
      `login` varchar(50) NOT NULL DEFAULT '',
      `password` varchar(50) NOT NULL DEFAULT '',
      PRIMARY KEY (`user_id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
    
    CREATE TABLE `Books` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `title` varchar(50) NOT NULL DEFAULT '',
      `author` varchar(50) NOT NULL DEFAULT '',
      `year` int(4) NOT NULL,
      `available` int(3) NOT NULL DEFAULT '0',
      `availabledate` date NOT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
    

    桥接表看起来像这样:

    CREATE TABLE books_users (
    book_id int(11) unsigned NOT NULL,
    user_id int(11) unsigned NOT NULL,
    PRIMARY KEY (book_id, user_id),
    KEY idx_user_id (user_id),
    FOREIGN KEY fk_books (book_id) REFERENCES Books(id),
    FOREIGN KEY fk_users (user_id) REFERENCES Users(user_id)
    ) ENGINE=InnoDB;
    

    这解决了这两个问题并且是常见的做法。

    要在一个查询中查询用户和图书,请按以下方式加入:

    SELECT
    whatever
    FROM
    Books b
    INNER JOIN books_users bu ON b.id = bu.book_id
    INNER JOIN users u ON bu.user_id = u.user_id
    WHERE user_id = 1 /*for example*/
    ;
    

    如果要在表中插入内容,只需执行insert并获取为SELECT LAST_INSERT_ID();行生成的id,然后将此id插入books_users桥表。

    更新不会影响任何内容,您可以在usersbooks上执行更新。如果你真的必须更新auto_increment列(通常不需要而不推荐),你可以在ON UPDATE CASCADE表中的外键之后添加books_users

答案 1 :(得分:0)

更改这些行并重试

  

user_id int(11) unsigned NOT NULL AUTO_INCREMENT更改为user_id int(11) NOT NULL AUTO_INCREMENT

  

id int(11)unsigned NOT NULL AUTO_INCREMENT,id int(11)NOT   NULL AUTO_INCREMENT,

  

user_id int(11)unsigned NOT NULL,user_id int(11)NOT NULL,

最后尝试

CREATE TABLE `Users` (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(50) NOT NULL DEFAULT '',
  `last_name` varchar(50) NOT NULL DEFAULT '',
  `login` varchar(50) NOT NULL DEFAULT '',
  `password` varchar(50) NOT NULL DEFAULT '',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;

CREATE TABLE `Books` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(50) NOT NULL DEFAULT '',
  `author` varchar(50) NOT NULL DEFAULT '',
  `year` int(4) NOT NULL,
  `available` int(3) NOT NULL DEFAULT '0',
  `availabledate` date NOT NULL,
  `user_id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

答案 2 :(得分:-2)

如果您使用的是Mysql,则必须使用InnoDB数据库引擎来启用两个表之间的关系 MyISAM不允许这种关系

alter table `users` add constraint `FK_users` FOREIGN KEY (`user_id`) REFERENCES `books` (`user_id`) ON DELETE NO ACTION  ON UPDATE NO ACTION 

或者您可以将此查询用于级联编辑删除

alter table `users` add constraint `FK_users` FOREIGN KEY (`user_id`) REFERENCES `books` (`user_id`) ON DELETE CASCADE  ON UPDATE CASCADE 

这是两个表的新DDL试试这个

CREATE TABLE IF NOT EXISTS `books` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(50) NOT NULL DEFAULT '',
  `author` varchar(50) NOT NULL DEFAULT '',
  `year` int(4) NOT NULL,
  `available` int(3) NOT NULL DEFAULT '0',
  `availabledate` date NOT NULL,
  `user_id` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

CREATE TABLE IF NOT EXISTS `users` (
  `user_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `first_name` varchar(50) NOT NULL DEFAULT '',
  `last_name` varchar(50) NOT NULL DEFAULT '',
  `login` varchar(50) NOT NULL DEFAULT '',
  `password` varchar(50) NOT NULL DEFAULT '',
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=15 ;

--
-- Constraints for dumped tables
--

--
-- Constraints for table `users`
--
ALTER TABLE `users`
  ADD CONSTRAINT `FK_users` FOREIGN KEY (`user_id`) REFERENCES `books` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;