Mysql 如果不存在(在单个查询中),是否插入一对多关系?

Mysql 如果不存在(在单个查询中),是否插入一对多关系?,mysql,sql,Mysql,Sql,考虑下表: 产品 +----+------+-------------+ | id | name | category_id | +----+------+-------------+ | 1 | foo | 1 | +----+------+-------------+ 类别 +----+------+ | id | name | +----+------+ | 1 | food | +----+------+ 现在假设有人发布了一个新产品: { "name"

考虑下表:

产品

+----+------+-------------+
| id | name | category_id |
+----+------+-------------+
| 1  | foo  |           1 |
+----+------+-------------+
类别

+----+------+
| id | name |
+----+------+
| 1  | food |
+----+------+
现在假设有人发布了一个新产品:

{
  "name": "bar",
  "category": "drink"
}
在这种情况下,我们需要自动创建新类别:

INSERT IGNORE INTO categories (name) VALUES ('drink')
然后,我们最终可以插入实际的产品行:

INSERT INTO products (name, category_id) VALUES ('bar', SELECT id FROM categories WHERE name = 'drink')

然而,尽管这样做可行,但需要安全的事务设置,因为这似乎不是一个超级复杂的查询,我想知道是否可以将两个查询合并在一起(例如,将类别的插入查询放入产品插入的选择子查询中)?否,这是不可能的。但是,您可以做的是在product表上插入触发器之前创建一个
,并检查触发器内部是否存在该类别。如果它不存在,您可以在那里创建它

触发器将在与
INSERT
-语句相同的事务中自动执行,因此不需要额外的事务

我看到的唯一问题是,当您忘记触发器时,您可能会开始纳闷,为什么每个新产品都会自动显示具有新类别的类别(类似的情况也发生在我身上)

更新:

您可以在中看到简单触发器的示例


您可以在插入前使用
new.column\u name
触发器中访问要插入的新值,因此对您来说,它将是
新的。类别
我建议不要
插入忽略
,原因是@Bill Karwin。此外,如以下文件所述:

如果表格包含
AUTO_INCREMENT
列并插入或更新行,则函数将返回
AUTO_INCREMENT
值。例外:对于更新,在MySQL 5.1.12之前没有意义。但是,您可以通过使用解决此问题。假设
id
AUTO_INCREMENT
列。要使更新有意义,请按如下方式插入行:

INSERT INTO table (a,b,c) VALUES (1,2,3)
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
然后可以获得
id
(无论是预先存在的还是新插入的),如下所述:

如果将记录插入到包含
AUTO_INCREMENT
列的表中,则可以通过调用函数获取存储在该列中的值

[ deletia ]
当然,如果需要原子性,这些语句仍然需要在事务中执行。

好主意!如何从触发器查询中访问类别名称?使用
NEW.category
-查看我的答案更新中的更多详细信息和链接我得到的是“新的未知列类别”?如何定义触发器?在哪个表上?在插入产品之前创建触发器类别插入忽略到类别(名称)值(新的.category);嘿,我读到了关于“插入…重复密钥更新”,但决定反对它,因为我读到它增加了自动递增计数器。这是真的吗?正常插入的行是否会跳过ID?@bodokaiser:请参阅。
INSERT INTO categories (name) VALUES ('drink')
  ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);

INSERT INTO products (name, category_id) VALUES ('bar', LAST_INSERT_ID());