【问题标题】:How to retrieve foreign key and INSERT INTO table (MySQL/InnoDB)如何检索外键和 INSERT INTO 表(MySQL/InnoDB)
【发布时间】:2011-11-14 12:44:55
【问题描述】:

我正在通过命令行和/或mysql> 提示符执行以下所有操作。

我是数据库新手,注意到有很多关于结构(教程)和定义(手册)的网站,但没有关于实际示例的网站。如果我有两张这样的桌子

CREATE TABLE IF NOT EXISTS owner
(
  ID INT NOT NULL AUTO_INCREMENT,
  name VARCHAR(32) NOT NULL UNIQUE,
  PRIMARY KEY(ID)
)ENGINE=InnoDB


CREATE TABLE IF NOT EXISTS dog
(
  ID INT NOT NULL AUTO_INCREMENT,
  owner INT NOT NULL,
  name VARCHAR(32) NOT NULL UNIQUE,
  PRIMARY KEY(ID),
  FOREIGN KEY (owner) REFERENCES owner(ID)
)ENGINE=InnoDB

如果我想添加到餐桌狗

INSERT INTO dog (owner, name) VALUES(get_owner_ID("Peter Griffin"), "Brian Griffin");

如何从名称(“Peter Griffin”)中获取神秘的所有者 ID

【问题讨论】:

  • 在执行insert 之前,您必须先以某种方式为Peter 提供select id(取决于您的业务逻辑)。
  • @kan 那是我迷路的地方。如果我这样做 select ID from owner where name = "Peter Griffin" 它返回一个表,而不是一个 int。你如何获得单一价值,我在哪里“存储”它?我会用它作为复合语句吗
  • 只需执行两个单独的查询 - 选择然后插入。并检查是否只返回一条记录(这意味着只有一条记录的 name = 'Peter')。

标签: mysql foreign-keys innodb


【解决方案1】:

您可以在插入dog 表时运行子选择,也可以创建自己的user defined function。用户定义的函数在这里比存储过程有优势,因为它可以在插入期间调用。因此:

CREATE TABLE IF NOT EXISTS owner
(
  ID INT NOT NULL AUTO_INCREMENT,
  name VARCHAR(32) NOT NULL UNIQUE,
  PRIMARY KEY(ID)
)ENGINE=InnoDB;

CREATE TABLE IF NOT EXISTS dog
(
  ID INT NOT NULL AUTO_INCREMENT,
  owner INT NOT NULL,
  name VARCHAR(32) NOT NULL UNIQUE,
  PRIMARY KEY(ID),
  FOREIGN KEY (owner) REFERENCES owner(ID)
)ENGINE=InnoDB;

现在创建函数:

DELIMITER //

DROP FUNCTION IF EXISTS get_owner_id//

CREATE FUNCTION get_owner_id(i_owner_name varchar(32)) returns integer 
READS SQL DATA
BEGIN
 declare v_owner_id int;
 select id into v_owner_id from owner where name = i_owner_name; 
 return v_owner_id;
END//

DELIMITER ;

insert into owner(name) values ('Peter Griffin');
insert into dog (owner,name) values (get_owner_id('Peter Griffin'),'Brian Griffin');

当然,您必须想办法处理 owner 表中不存在所有者的情况。也许在所有者表中有一个默认的“未知所有者”,如果没有找到所有者,则从函数中返回它?取决于你...

【讨论】:

  • 这是个好主意,还是我应该将所有者 ID 全部删除,然后将名称用作主键?我不这样做的唯一原因是因为每个网站(包括这个网站)都说最好使用不相关的整数作为主键。
  • 啊。好吧,您进入了“自然与代理”主键的粘性世界。人们似乎在为较小的问题而战!就个人而言,我认为您拥有的表格设计(ID = PK,然后是名称列上的唯一键)是一个很好的方法,您应该保持原样。 “替代与自然”的争论太大,无法放入此评论框。
  • 你有什么理由使用反引号吗?如果我将其复制粘贴到mysql> 中,它可以工作。但是如果我将它输入到控制台 mysql --user=<user> --password=<passwd> << EOFMYSQL 我会收到语法错误。
  • 如果有人在 shell 中执行此操作,请使用反斜杠转义反引号并将分隔符从 $$ 更改为其他内容,例如 //
  • 真的没有。您可以安全地删除反引号并使用不同的分隔符。我将编辑我的答案。
猜你喜欢
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 2015-05-12
  • 2014-05-30
  • 2012-04-14
  • 1970-01-01
  • 1970-01-01
  • 2021-04-29
相关资源
最近更新 更多