我在大学的数据库类(class)中使用 Mysql Workbench,尽管它使用起来非常简单,但有些事情我无法解决。
现在,我一直在尝试建立一个类似百视达的商店模型。在我的“租赁”页面上,我想添加 Exp_Ret_Date、Act_Ret_Date 和 Book_Date。现在,Book_Date 和 Exp_Ret_Date 有两个默认值:Book_Date 是 NOW(),而 Exp_Ret_Date 应该是 Book_Date 之后 2 天。
因此,我尝试在默认阵营中写入 DATE_ADD(NOW(), INTERVAL 2 DAY),但它不起作用。我尝试使用 TIMESTAMP、CURDATE、ADDDATE 以及我能想到的任何其他方法,但效果不佳。因此,如果有人能够指导我如何解决这个问题,我和我的同学将非常感激。
这是 MySQL Workbench 生成的完整代码。它一直说 DATE_ADD 部分的行中有语法错误。
-- MySQL Workbench Forward Engineering
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL,ALLOW_INVALID_DATES';
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
-- -----------------------------------------------------
-- Schema mydb
-- -----------------------------------------------------
CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
USE `mydb` ;
-- -----------------------------------------------------
-- Table `mydb`.`MEMBER`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`MEMBER` (
`MEMBER_ID` INT(10) NOT NULL,
`LAST_NAME` VARCHAR(25) NOT NULL,
`FIRST_NAME` VARCHAR(25) NULL,
`ADDRESS` VARCHAR(100) NULL,
`CITY` VARCHAR(30) NULL,
`PHONE` VARCHAR(15) NULL,
`JOIN_DATE` DATETIME NOT NULL DEFAULT NOW(),
PRIMARY KEY (`MEMBER_ID`),
UNIQUE INDEX `MEMBER_ID_UNIQUE` (`MEMBER_ID` ASC))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`TITLE`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`TITLE` (
`TITLE_ID` INT(10) NOT NULL,
`TITLE` VARCHAR(60) NOT NULL,
`DESCRIPTION` VARCHAR(400) NOT NULL,
`RATING` ENUM('G','PG','R','NC17','NR') NULL,
`CATEGORY` ENUM('DRAMA','COMEDY','ACTION','CHILD','SCIFI','DOCUMENTARY') NULL,
`RELEASE_DATE` DATETIME NULL,
PRIMARY KEY (`TITLE_ID`),
UNIQUE INDEX `TITLE_ID_UNIQUE` (`TITLE_ID` ASC))
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`TITLE_COPY`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`TITLE_COPY` (
`COPY_ID` INT(10) NOT NULL,
`STATUS` ENUM('AVAILIBLE','DESTROYED','RENTED','RESERVED') NOT NULL,
`TITLE_ID` INT(10) NOT NULL,
PRIMARY KEY (`COPY_ID`, `TITLE_ID`),
UNIQUE INDEX `COPY_ID_UNIQUE` (`COPY_ID` ASC),
INDEX `fk_TITLE_COPY_TITLE_idx` (`TITLE_ID` ASC),
CONSTRAINT `fk_TITLE_COPY_TITLE`
FOREIGN KEY (`TITLE_ID`)
REFERENCES `mydb`.`TITLE` (`TITLE_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`RENTAL`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`RENTAL` (
`BOOK_DATE` DATETIME NOT NULL DEFAULT NOW(),
`ACT_RET_DATE` DATETIME NULL,
`EXP_RET_DATE` DATETIME NULL DEFAULT NOW() + INTERVAL 2 DAY,
`MEMBER_ID` INT(10) NOT NULL,
`COPY_ID` INT(10) NOT NULL,
`TITLE_ID` INT(10) NOT NULL,
PRIMARY KEY (`BOOK_DATE`, `COPY_ID`, `TITLE_ID`, `MEMBER_ID`),
UNIQUE INDEX `BOOK_DATE_UNIQUE` (`BOOK_DATE` ASC),
INDEX `fk_RENTAL_MEMBER1_idx` (`MEMBER_ID` ASC),
INDEX `fk_RENTAL_TITLE_COPY1_idx` (`COPY_ID` ASC, `TITLE_ID` ASC),
CONSTRAINT `fk_RENTAL_MEMBER1`
FOREIGN KEY (`MEMBER_ID`)
REFERENCES `mydb`.`MEMBER` (`MEMBER_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_RENTAL_TITLE_COPY1`
FOREIGN KEY (`COPY_ID` , `TITLE_ID`)
REFERENCES `mydb`.`TITLE_COPY` (`COPY_ID` , `TITLE_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
-- -----------------------------------------------------
-- Table `mydb`.`RESERVATION`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `mydb`.`RESERVATION` (
`RES_DATE` DATETIME NOT NULL DEFAULT NOW(),
`MEMBER_ID` INT(10) NOT NULL,
`TITLE_ID` INT(10) NOT NULL,
PRIMARY KEY (`RES_DATE`, `MEMBER_ID`, `TITLE_ID`),
INDEX `fk_RESERVATION_MEMBER1_idx` (`MEMBER_ID` ASC),
INDEX `fk_RESERVATION_TITLE1_idx` (`TITLE_ID` ASC),
CONSTRAINT `fk_RESERVATION_MEMBER1`
FOREIGN KEY (`MEMBER_ID`)
REFERENCES `mydb`.`MEMBER` (`MEMBER_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION,
CONSTRAINT `fk_RESERVATION_TITLE1`
FOREIGN KEY (`TITLE_ID`)
REFERENCES `mydb`.`TITLE` (`TITLE_ID`)
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
预先感谢您提供的任何帮助。错误出现在第 72 行左右。
最佳答案
UNIQUE INDEX
定义是多余的,其中大部分是不需要的。
例如,MEMBER_ID
已定义为 PRIMARY KEY
;将该列作为前导列的第二个唯一索引并不是真正必要的。
PRIMARY KEY (`MEMBER_ID`),
UNIQUE INDEX `MEMBER_ID_UNIQUE` (`MEMBER_ID` ASC))
我可以理解InnoDB不会抛出异常;某些查询可能能够使用“窄”索引,但第二个索引实际上可以提高性能的情况很少见。同样的事情也适用于此:
PRIMARY KEY (`TITLE_ID`),
UNIQUE INDEX `TITLE_ID_UNIQUE` (`TITLE_ID` ASC))
UNIQUE INDEX
是多余的,因为 TITLE_ID
已定义为表的唯一簇键。
这有点奇怪,COPY_ID
是唯一的,但 PRIMARY KEY
被定义为该唯一列和第二列的组合:
PRIMARY KEY (`COPY_ID`, `TITLE_ID`),
UNIQUE INDEX `COPY_ID_UNIQUE` (`COPY_ID` ASC),
只需将COPY_ID
设置为表的PRIMARY KEY
就足够了。同样适用于此...
PRIMARY KEY (`BOOK_DATE`, `COPY_ID`, `TITLE_ID`, `MEMBER_ID`),
UNIQUE INDEX `BOOK_DATE_UNIQUE` (`BOOK_DATE` ASC),
但在这种情况下,我怀疑 BOOK_DATE
实际上并不唯一。如果是,则不需要复合主键。
要让数据库在插入行时自动为列分配值,您可以定义 BEFORE INSERT
触发器。 (正如 Barmar 在他的评论中指出的那样,MySQL 在接受默认值方面受到限制......它必须是一个文字值,它不能是一个表达式。(有一个小异常(exception)对于 TIMESTAMP
列的 CURRENT_TIMESTAMP
;过去您只能在数据类型 TIMESTAMP
的列上执行此操作,但我认为 MySQL 的更新版本支持类似“DATETIME 列”的内容。)
作为触发器的简单示例:
DELIMITER $$
CREATE TRIGGER mytable_bi
BEFORE INSERT ON mytable
FOR EACH ROW
BEGIN
SET NEW.exp_ret_date = NOW() + INTERVAL 2 DAY;
END$$
DELIMITER ;
触发器将覆盖提供的任何值。您可以在触发器中执行条件测试,以检查列值是否为 NULL,然后再为其赋值:
IF NEW.exp_ret_date IS NULL THEN
SET NEW.exp_ret_date = NOW() + INTERVAL 2 DAY;
END IF;
关于mysql - 添加一列,默认值为后天日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28619913/