【问题标题】:Error Number: 1452 Cannot add or update a child row: a foreign key constraint fails错误号:1452 无法添加或更新子行:外键约束失败
【发布时间】:2018-05-14 14:25:29
【问题描述】:

作为练习,我正在尝试使用 CodeIgniter 创建一个非常基本的 Twitter 克隆。我目前正在尝试创建一个简单的注册/注册表单来创建一个帐户并将其添加到数据库表users。 这些字段是名字用户名电子邮件地址密码密码确认

但是,我收到以下错误。

错误号:1452

无法添加或更新子行:外键约束失败(lamp.users, CONSTRAINT users_ibfk_1 FOREIGN KEY (user_id) REFERENCES tweets (user_id))

插入usersfirst_namelast_nameusernameemailpassword)值('fn'、'ln'、'用户名'、'user@gmail.com' , 'pw')

文件名:models/User_model.php

行号:33

我使用 user_id 列在我的 Tweet_model.php 中加入了我的两个表 userstweets表。

两个表中 user_id 的结构是:

推文表

字段:user_id,类型:INT,长度:11,无符号,密钥:MUL

用户表

字段:user_id,类型:INT,长度:11,无符号,密钥:PRI,额外:auto_increment

我的代码如下:

控制器: Register.php

class Register extends CI_Controller
{
public function index()
{
  $this->load->model('user_model');

  $this->form_validation->set_rules('first_name', 'First Name', 'required');
  $this->form_validation->set_rules('last_name', 'Last Name', 'required');
  $this->form_validation->set_rules('username', 'Username', 'required');
  $this->form_validation->set_rules('email', 'Email', 'required');
  $this->form_validation->set_rules('password', 'Password', 'required');
  $this->form_validation->set_rules('passconf', 'Password Confirmation', 'required');

    if ($this->form_validation->run() == false) {
        $this->load->view('templates/header');
        $this->load->view('register');
        $this->load->view('templates/footer');
    } else {
        $this->user_model->set_user();
        $this->load->view('templates/header');
        $this->load->view('home');
        $this->load->view('templates/footer');
    }
  }
}

型号: User_model.php

class User_model extends CI_Model
{
public function __construct()
{
    $this->load->database();
}

public function get_users($user_id = false)
{
    if ($user_id === false) {
        $query = $this->db->get('users');
        return $query->result_array();
    }

    $query = $this->db->get_where('users', array('user_id' => $user_id));
    return $query->row_array();
}

public function set_user()
{
    $url = url_title($this->input->post('user'), 'dash', true);

    $data = array(
      'first_name' => $this->input->post('first_name'),
      'last_name' => $this->input->post('last_name'),
      'username' => $this->input->post('username'),
      'email' => $this->input->post('email'),
      'password' => $this->input->post('password')
    );

    return $this->db->insert('users', $data);
}
}

查看: register.php

<form action="/index.php/register" method="POST">

  <h5>First Name</h5>
  <input type="text" name="first_name" value="" size="50" />

  <h5>Last Name</h5>
  <input type="text" name="last_name" value="" size="50" />

  <h5>Username</h5>
  <input type="text" name="username" value="" size="50" />

  <h5>Email Address</h5>
  <input type="text" name="email" value="" size="50" />

  <h5>Password</h5>
  <input type="text" name="password" value="" size="50" />

  <h5>Password Confirm</h5>
  <input type="text" name="passconf" value="" size="50" />

  <div><input type="submit" value="Register" /></div>

</form>

Tweet_model.php

class Tweet_model extends CI_Model
{
public function __construct()
{
    $this->load->database();
}

public function get_tweets($tweet_id = false)
{
    if ($tweet_id === false) {
        $this->db->join('users', 'tweets.user_id = users.user_id');
        $query = $this->db->get('tweets');
        return $query->result_array();
    }

    $query = $this->db->get_where('tweets', array('tweet_id' => $tweet_id));
    return $query->row_array();
}

public function set_tweet()
{
    $tweet = url_title($this->input->post('tweet'), 'dash', true);

    $data = array(
    'tweet' => $this->input->post('tweet')
);

    return $this->db->insert('tweets', $data);
}
}

编辑:是它倒退了。但是现在我想发布推文时遇到了同样的问题。

错误号:1452

无法添加或更新子行:外键约束失败(lamp.tweets, CONSTRAINT tweets_ibfk_1 FOREIGN KEY (user_id) REFERENCES users (user_id))

插入tweets (tweet) 值(“测试推文”)

文件名:models/Tweet_model.php

行号:30

【问题讨论】:

  • 用户表上是否有引用推文表的外键?应该反过来。
  • 好的,这是因为我在 Tweet_model 中加入表格的方式?

标签: php mysql database codeigniter


【解决方案1】:

似乎外键约束是向后定义的。

我不了解问题中展示的特定用例...但我怀疑这是usertweet 之间的一对多关系

tweet 被一个 user 推特。

user 可以 twit 零个、一个或多个 tweet

通常,我们使用外键实现一对多关系,从“多”端指向“一”端

例如

 CREATE TABLE tweet 
 ( ...
 , user_id
 , ...
 , CONSTRAINT FK_tweet_user FOREIGN KEY (user_id) REFERENCES user (id) 
 , ...

此约束将阻止将具有“无效”user_id(未引用 user 中的行的值)的行添加到 tweet


如果我们反向定义外键,反之,我们将阻止在tweet 中找不到匹配值时向user 添加一行。也就是说,在tweet 中为该用户找到一行之前,我们无法添加该用户。

编辑

一旦外键以正确的方式翻转,当我们向tweet 插入一行时,我们需要为user_id 列提供一个值。

INSERT INTO tweet (user_id, tweet) VALUES 
--                 ^^^^^^^^
(  42, 'rt this if you’re ready for #NoMore with @PRETTYMUCH and @FrencHMonTanA' )
;
-- ^^^ 

【讨论】:

  • “直到我们在推文中为该用户添加一行之后才能添加用户” - 因为它会阻止一些推文被写入,所以它可能是好东西。 :-o
  • 好的,所以这意味着我必须更正我在 Tweet_model.php 中所做的连接是否正确?也许将它放在 User_model.php 中?
  • @MagnusEriksson:我没有资格做出判断... :-o
  • @migs:我看不出有什么需要用join 中的get_tweets 进行更改。我觉得这很好。
  • 好的,谢谢,我想通了,并从 users 表中删除了关系。直到现在,我在发布新推文时才遇到类似的关系问题。如果我不能将 user_id 用于 users 表,我该怎么做?我对问题进行了编辑。
【解决方案2】:

user_id 是 AUTO_INCREMENT 吗?如果没有,您将始终尝试插入 user_id 0(默认 INT 值),因为它是唯一的,所以它会失败。

【讨论】:

  • 它是用于 users 表的,但不会将它设置为 tweets 表的 auto_increment 导致 user_id 每次发布新推文时都会增加?或者它们是否必须在两个表中完全相同才能正常工作?
  • 哦,我明白了。您在用户和推文之间使用 fk。但它似乎是在相反的方向。您需要 TWEETS 表中的外键,其中 user_id 等于 USERS.user_id。你是在倒着做吗?
  • 是的,就是这样。但是现在我在发布推文时遇到了同样的问题。如果我不能只在 users 表上使用 user_id,我将如何设置两个表之间的关系?
  • 如果你做得好,你不应该有同样的问题。仅当 user_id 不存在于 USERS 表中时,Foreing 键才会阻止您插入新推文。 users.user_id 是主键吗?编辑:当然要确保您插入的推文的 user_id 对应于现有用户。
  • 好的,这可能是因为我还没有正确设置我的登录会话,以便知道哪个用户登录并发布推文。
猜你喜欢
  • 1970-01-01
  • 2014-05-10
  • 2015-02-04
  • 2013-06-11
  • 2019-03-29
  • 2013-05-11
  • 2013-09-28
  • 1970-01-01
  • 2014-01-06
相关资源
最近更新 更多