SQL FOREIGN KEY USAGE?它到底是做什么的?什么时候需要?

时间:2010-07-16 09:04:21

标签: php sql mysql database database-design

好吧我为我的例子制作了一个简单的数据库,有用户数据和用户公司的数据。

CREATE TABLE `users` (
  `UID` INT(25) NOT NULL AUTO_INCREMENT ,
  `username` VARCHAR(60) NOT NULL ,
  `password` VARCHAR(100) NOT NULL ,
  `ownername` VARCHAR(150) NOT NULL ,
  `userstatus` TINYINT(1) NOT NULL ,
  `userregistertime` DATETIME NOT NULL ,
  `userlastonline` DATETIME NOT NULL ,
  PRIMARY KEY (`UID`) ,
  INDEX `username` (`username` ASC) )
  ENGINE = InnoDB
  DEFAULT CHARACTER SET = utf8;

CREATE TABLE `company` (
  `CID` INT(25) NOT NULL AUTO_INCREMENT ,
  `UID` INT(25) NOT NULL ,
  `companyname` VARCHAR(60) NOT NULL ,
  `companyaddress` VARCHAR(255) NOT NULL ,
  `companyemail` VARCHAR(255) NULL DEFAULT NULL ,
  `companyphone` VARCHAR(20) NOT NULL ,
  `companyimage` VARCHAR(255) NULL DEFAULT NULL ,
  `companyyahoo` VARCHAR(255) NULL DEFAULT NULL ,
  `companytwitter` VARCHAR(255) NULL DEFAULT NULL ,
  `companykaskus` VARCHAR(255) NULL DEFAULT NULL ,
  `companyfacebook` VARCHAR(255) NULL DEFAULT NULL ,
  `companytype` TINYINT(1) NOT NULL DEFAULT '0' ,
  `companystatus` TEXT NULL DEFAULT NULL ,
  `companytemplate` TEXT NULL DEFAULT NULL ,
  `companyintroduction` TEXT NULL DEFAULT NULL ,
  `partnership` TINYINT(1) NOT NULL DEFAULT '0' ,
  PRIMARY KEY (`CID`) ,
  INDEX `ownername` (`UID` ASC) ,
  INDEX `companyname` (`companyname` ASC) ,
  CONSTRAINT `ownernamecompany`
    FOREIGN KEY (`UID` )
    REFERENCES `users` (`UID` )
    ON DELETE CASCADE
    ON UPDATE CASCADE)
ENGINE = InnoDB
DEFAULT CHARACTER SET = utf8;

1.为什么我将数据插入users表(uid是自动增量)后它不会更新我公司的UID表?

如果你有PHP知识,请看我是如何插入的。

$RegisterInsert1 = $dbConnect->prepare("INSERT INTO users (
`username`, `password`, `ownername`, `userregistertime`, `userlastonline`) VALUES (
:username, :password, :ownername, :userregistertime, :userlastonline)");
$RegisterInsert1->execute($RegisterData1); 

如你所见,我得到,UID = 1(自动),然后在用户表上插入用户名,密码,所有者名等。但不知何故,我公司的UID没有更新。它应该是UID = 1然后其余的CID(auto)companyname null,等等。

2.am我正确定义外键使用?

3.请给我一个最好的例子,插入用户数据+公司数据,并使用正确的国外用法。

我现在怎么做

// INSERT USERS DB
$RegisterInsert1 = $dbConnect->prepare("INSERT INTO users (
`username`, `password`, `ownername`, `userregistertime`, `userlastonline`) VALUES (
:username, :password, :ownername, :userregistertime, :userlastonline)");
$RegisterInsert1->execute($RegisterData1);

// GET USERS GIVEN AUTO GENERATED UID
// QUESTION ? THIS one should be automated by foreign useage ?
$GetUid = $dbConnect->prepare("SELECT UID FROM users WHERE username = :username");
$GetUid->execute($RegisterData3);
$UserID = $GetUid->fetch();
$RegisterData2['UID'] = $UserID;

// INSERT COMPANY INFO + UID
$RegisterInsert2 = $dbConnect->prepare("INSERT INTO company (
`UID`,`companyphone`,`partnership`) VALUES (
:UID, :companyphone, :partnership)");
$RegisterInsert2->execute($RegisterData2);

2 个答案:

答案 0 :(得分:3)

架构定义中的外键是Company表中的UID列。这指的是Users表中的单行。您可以通过添加外键约束来确保永远不会将无效的UID插入到Company表中。

ALTER TABLE COMPANY ADD FOREIGN KEY COMPANY_USER_FK (UID) REFERENCES USER(UID);

这将导致尝试将UID添加到User表中不存在的公司名称中以使其失败。您可以添加额外的功能,以便从User表中删除用户删除Company表中的所有匹配行,如下所示...

ALTER TABLE COMPANY ...etc... REFERENCES USER(UID) ON DELETE CASCADE;

或者您可以阻止用户被删除,如果公司表中的行存在...

ALTER TABLE COMPANY ...etc... REFERENCES USER(UID) ON DELETE RESTRICT;

虽然它不适用于您的架构,但您也可以通过以下方式将更改级联到Users表中的UID

ALTER TABLE COMPANY ...etc... REFERENCES USER(UID) ON UPDATE CASCADE;

请注意,如果存储引擎为INNODB;

,则所有这些仅适用于MySQL

答案 1 :(得分:0)